2017-05-14

Scrapy入门教程

作者:开挂的柑桔 来源:大事记 我要评论(0) 浏览(229)

Scrapy入门教程

一、   了解Scrapy

Scrapy 是一套基于Twisted的异步处理框架,是纯python实现的爬虫框架,是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。  

二、   框架

Scrapy的大体架构,其中包含了scheduler、item pipeline、downloader、spider以及engine这几个组件模块

blob.png

1.组件说明

1).Scrapy Engine(Scrapy引擎)

     Scrapy引擎是用来控制整个系统的数据处理流程,并进行事务处理的触发。更多的详细内容可以看下面的数据处理流程。

2).Scheduler(调度)

    调度程序从Scrapy引擎接受请求并排序列入队列,并在Scrapy引擎发出请求后返还给他们。

3).Downloader(下载器)

    下载器的主要职责是抓取网页并将网页内容返还给蜘蛛( Spiders)。

4).Spiders(蜘蛛)

     蜘蛛是有Scrapy用户自己定义用来解析网页并抓取制定URL返回的内容的类,每个蜘蛛都能处理一个域名或一组域名。换句话说就是用来定义特定网站的抓取和解析规则。

     蜘蛛的整个抓取流程:

  • 首先获取第一个URL的初始请求,当请求返回后调取一个回调函数。

  • 在回调函数中,你可以解析网页响应并返回项目对象和请求对象或两者的迭代。

  • 在回调函数中,你解析网站的内容,并生成解析的数据项。

  • 最后,从蜘蛛返回的项目通常会进驻到项目管道。

5).Item Pipeline(项目管道)

    项目管道的主要责任是负责处理有蜘蛛从网页中抽取的项目,他的主要任务是清晰、验证和存储数据。

    项目管道通常执行的过程有:

  • 清洗HTML数据

  • 验证解析到的数据(检查项目是否包含必要的字段)

  • 检查是否是重复数据(如果重复就删除)

  • 将解析到的数据存储到数据库中

  • 数据处理流程

6).处理流程

     Scrapy的整个数据处理流程由Scrapy引擎进行控制,其主要的运行方式为:

  • 引擎打开一个域名,时蜘蛛处理这个域名,并让蜘蛛获取第一个爬取的URL。

  • 引擎从蜘蛛那获取第一个需要爬取的URL,然后作为请求在调度中进行调度。

  • 引擎从调度那获取接下来进行爬取的页面。

  • 调度将下一个爬取的URL返回给引擎,引擎将他们通过下载中间件发送到下载器。

  • 当网页被下载器下载完成以后,响应内容通过下载中间件被发送到引擎。

  • 引擎收到下载器的响应并将它通过蜘蛛中间件发送到蜘蛛进行处理。

  • 蜘蛛处理响应并返回爬取到的项目,然后给引擎发送新的请求。

  • 引擎将抓取到的项目项目管道,并向调度发送请求。

  • 系统重复第二部后面的操作,直到调度中没有请求,然后断开引擎与域之间的联系。

三、   安装指南

安装检查

  • Python2.7

  • Python Package: pip and setuptools. 现在 pip 依赖 setuptools ,如果未安装,则会自动安装 setuptools 。

  • lxml. 大多数Linux发行版自带了lxml。如果缺失,请查看http://lxml.de/installation.html

  • OpenSSL. 除了Windows(请查看 平台安装指南)之外的系统都已经提供。

四、   开发流程

  • 新建项目 (Project):新建一个新的爬虫项目

  • 明确目标(Item):定义提取的Item

  • 制作爬虫(Spider):编写爬取网站的 spider 并提取 Item

  • 存储内容(Pipeline):编写 Item Pipeline 来存储提取到的Item(即数据)

1.    新建项目(Project)

     在任意目录下按住Shift键右击,选择“在此处打开命令窗口”,输入一下命令:

scrapy startproject sjzxetl

    将会创建一个sjzxetl文件夹,目录结构如下:


 blob.png

 

 

 

 

 

各个文件的作用:

  • scrapy.cfg:项目的配置文件

  • sjzxetl /:项目的Python模块,将会从这里引用代码

  • sjzxetl /items.py:项目的items文件

  • sjzxetl /pipelines.py:项目的pipelines文件

  • sjzxetl /settings.py:项目的设置文件

  • sjzxetl /spiders/:存储爬虫的目录

2.    定义Item

Item 是保存爬取到的数据的容器;提供了额外保护机制来避免拼写错误导致的未定义字段错误。您可以通过创建一个 scrapy.Item 类, 并且定义类型为 scrapy.Field 的类属性来定义一个Item

class ws_r_eventinfo(Item):    SOURCE_CODE = Field()
    EVENT_ID = Field()
    THEME_NAME = Field()
    EVENT_TITLE = Field()
    MOVEMENT_INDEX = Field()
    HOT_INDEX = Field()
    NEWS_CONTENT = Field()
    PUBLISH_TIME = Field()
    UPDATE_TIME = Field()

3.    编写爬虫(Spider)

为了创建一个Spider,您必须继承 scrapy.Spider 类, 且定义以下三个属性:

  • name: 用于区别Spider。 该名字必须是唯一的,您不可以为不同的Spider设定相同的名字。

  • start_urls: 包含了Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一。 后续的URL则从初始的URL获取到的数据中提取。

  • parse() 是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。

import scrapy

class yun_to_raw(Spider):
    def __init__(self):
        self.name = 'xx_hotnews'
        self.allowed_domains = ['www.xx.com']
        #, 'www.xx.com/markethot', 'www.xx.com/story/details'
        self.start_urls = ['http://www.xx.com/xx_news.html']def parse(self, response):
        xpath_loop = response.xpath('//section[@id="container"]/div[1]/ul[1]/li')

Scrapy为Spider的 start_urls 属性中的每个URL创建了 scrapy.Request 对象,并将 parse 方法作为回调函数(callback)赋值给了Request。

Request对象经过调度,执行生成 scrapy.http.Response 对象并送回给spider parse() 方法。

4.    提取Item

Scrapy使用了一种基于 XPath 和 CSS 表达式机制: Scrapy Selectors 。  

def parse(self, response):

        xpath_loop = response.xpath('//section[@id="container"]/div[1]/ul[1]/li')

result_list = []        for sel in xpath_loop:

            #主页面内容

            driver_content_href = sel.xpath('.//div[@class="content1"]/a/@href').extract()[0]

            news_href = sel.xpath('.//div[@class="content1"]/h3/a/@href').extract()[0]

            theme = sel.xpath('.//div[@class="content1"]/h3/a/text()').extract()[0]

            publish_time = sel.xpath('.//div[@class="content1"]/h3/span/text()').extract()[0]

Selector有四个基本的方法(点击相应的方法可以看到详细的API文档):

  • xpath(): 传入xpath表达式,返回该表达式所对应的所有节点的selector list列表 。

  • css(): 传入CSS表达式,返回该表达式所对应的所有节点的selector list列表.

  • extract(): 序列化该节点为unicode字符串并返回list。

  • re(): 根据传入的正则表达式对数据进行提取,返回unicode字符串list列表。

5.    使用item

Item 对象是自定义的python字典。 您可以使用标准的字典语法来获取到其每个字段的值。(字段即是我们之前用Field赋值的属性):

item = ws_r_eventinfo()
item['SOURCE_CODE'] = self.source_code
item['EVENT_ID'] = self.id
item['THEME_NAME'] = theme
item['EVENT_TITLE'] = title
item['MOVEMENT_INDEX'] = index_change
item['HOT_INDEX'] = index_hot
item['PUBLISH_TIME'] = publish_time

 

6.    保存数据

当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理。

每个item pipeline组件(有时称之为“Item Pipeline”)是实现了简单方法的Python类。他们接收到Item并通过它执行一些行为,同时也决定此Item是否继续通过pipeline,或是被丢弃而不再进行处理。

以下是item pipeline的一些典型应用:

  • 清理HTML数据

  • 验证爬取的数据(检查item包含某些字段)

  • 查重(并丢弃)

  • 将爬取结果保存到数据库中

每个item pipeline组件都需要调用process_item方法,这个方法必须返回一个 Item (或任何继承类)对象, 或是抛出 DropItem 异常,被丢弃的item将不会被之后的pipeline组件所处理。

process_item(self, item, spider)

7.    启用Item Pipeline组件

为了启用一个Item Pipeline组件,你必须将它的类添加到 ITEM_PIPELINES 配置,就像下面这个例子:

settings.set("ITEM_PIPELINES", {    
   'sjzxetl.pipelines.YunPipeline': 100})

 

8.    爬取

使用proces.crawl来调用spider。通过该方式可调用自定义settings

from sjzxetl.spiders.yun.yun import yun_to_raw 
process.crawl(yun_to_raw) process.start()

 

五、   开发问题:

  • 数据源样式改版

  • 验证码识别

  • JS加载

六、   参考资料:

http://python.usyiyi.cn/translate/python_278/index.html

http://scrapy-chs.readthedocs.io/zh_CN/latest/


1.大事记平台遵循《互联网新闻信息服务管理规定》, 本网站不做时政、军事、新闻等采编操作,不干预新闻信息呈现或搜索结果等手段谋取不正当利益行业规范。 2.大事记平台的资讯均来自网络,如有侵权,请联系我们。3.如果您认为本网站有帮助,或者希望本站呈现更多内容,请多多支持本站!

网友评论

没有 Brand 不能评论 否则请刷新页面