Date: 2019-07-07html
Author: Sunpython
Scrapy,Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途普遍,能够用于数据挖掘、监测和自动化测试。web
Scrapy是一个为遍历爬行网站、分解获取数据而设计的应用程序框架,它能够应用在普遍领域:数据挖掘、信息处理和或者历史片(历史记录)打包等等shell
官方网站:http://scrapy.org数据库
scrapy框架的安装依赖于异步网络库twisted,安装过程很简单。cookie
进入到python虚拟环境下:网络
pip install Scrapy架构
安装过程当中可能存在以下问题?框架
building 'twisted.test.raiser' extension
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools异步
解决方案
进入下载页面:http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
下载twisted对应版本的whl文件(如个人Twisted-17.5.0-cp36-cp36m-win_amd64.whl),cp后面是python版本,amd64表明64位,运行命令:
pip install C:\Users\CR\Downloads\Twisted-17.5.0-cp36-cp36m-win_amd64.whl
在此安装scrapy
pip install Scrapy
说明:
若是发现哪一个库安装失败,则经过wget下载https://pypi.org/simple/中相应版本的库,并安装,最后安装就能够成功
Scrapy框架主要由六大组件组成,它们分别是调试器(Scheduler)、下载器(Downloader)、爬虫(Spider)、中间件(Middleware)、实体管道(Item Pipeline)和Scrapy引擎(Scrapy Engine)
下面的图表显示了Scrapy架构组件。
scrapy基本组件图
组件说明:
(1)Scrapy Engine
引擎负责控制数据流在系统中全部组件中流动,并在相应动做发生时触发事件。
(2)调度器(Scheduler)
调度器从引擎接受request对象,并将他们入队列,以便以后引擎请求他们时提供给引擎。
(3)下载器(Downloader)
下载器负责获取页面数据并提供给引擎,然后提供给spiders。
(4)Spiders
Spider是Scrapy用户编写用于分析response并提取item(即获取到的item)或额外跟进的URL的类。 每一个spider负责处理一个特定(或一些)网站。 更多内容请看 Spiders 。
(5)Item Pipeline
Item Pipeline负责处理被spider提取出来的item。典型的处理有清理、 验证及持久化(例如存取到数据库中)。 更多内容查看 Item Pipeline。
(6)下载器中间件(Downloader middlewares)
下载器中间件是在引擎及下载器之间的特定钩子(specific hook),处理Downloader传递给引擎的response(也包括引擎传递给下载器的Request)。 其提供了一个简便的机制,经过插入自定义代码来扩展Scrapy功能。更多内容请看 下载器中间件(Downloader Middleware) 。
一句话总结就是:处理下载请求部分
(7)Spider中间件(Spider middlewares)
Spider中间件是在引擎及Spider之间的特定钩子(specific hook),处理spider的输入(response)和输出(items及requests)。 其提供了一个简便的机制,经过插入自定义代码来扩展Scrapy功能。更多内容请看 Spider中间件(Middleware) 。
数据流程图以下:
scrapy数据流图
Scrapy数据流图是由执行的核心引擎(engine)控制,流程是这样的:
一、爬虫引擎得到初始请求开始抓取。
二、爬虫引擎开始请求调度程序,并准备对下一次的请求进行抓取。
三、爬虫调度器返回下一个请求给爬虫引擎。
四、引擎请求发送到下载器,经过下载中间件下载网络数据。
五、一旦下载器完成页面下载,将下载结果返回给爬虫引擎。
六、引擎将下载器的响应经过中间件返回给爬虫进行处理。
七、爬虫处理响应,并经过中间件返回处理后的items,以及新的请求给引擎。
八、引擎发送处理后的items到项目管道,而后把处理结果返回给调度器,调度器计划处理下一个请求抓取。
九、重复该过程(继续步骤1),直到爬取完全部的url请求。
Scrapy的Request和Response对象用于爬取web网站。
通常来讲,Request对象在
spider
中被生成而且最终传递到下载器(Downloader
),下载器对其进行处理并返回一个Response
对象,Response
对象还会返回到生成request
的spider
中。
一个Request对象表明一个HTTP请求,通常来说,HTTP请求是由Spider
产生并被Downloader
处理进而生成一个Response。
4.2.1 构造方法:
class scrapy.http.Request(url[, callback, method='GET', headers, body, cookies, meta, encoding='utf-8', priority=0, dont_filter=False, errback, flags])
一个Request对象表示一个HTTP 请求,它一般在Spider中生成并由Downloader执行,从而生成一个。
参数: url(string):请求的url callback(callable):处理响应数据的回调方法,用来解析响应数据,若是没有指定,则spider的parse方法。若是在处理期间引起异常,则会调用errback。 method(string):HTTP的请求方法。默认GET。 meta(dict):Request.meta属性的初始值。一旦此参数被设置,经过参数传递的字典将会被浅拷贝。 body:请求体。 headers(dict):请求头。 cookies(dict):cookie encoding(string):编码方式,默认utf-8。 priority(int):优先级,调度程序使用优先级来定义用于处理请求的顺序。具备较高优先级值的请求将会提早执行。默认0。 dont_filter(boolean):请求不该该被调度器过滤。False表示过滤,True表示不过滤。默认False。 errback(callable):若是在处理请求时引起异常,将会调用该函数。 这包括404 HTTP错误等失败的页面。
4.2.2. Request.meta
Request.meta在不一样的请求之间传递数据使用的 Request.meta属性能够包含任意的数据,可是Scrapy和它的内置扩展能够识别一些特殊的键。 dont_redirect:不重定向 dont_retry:不重试 handle_httpstatus_list dont_merge_cookies:不合并cookie cookiejar:使用cookiejar redirect_urls:重定向链接 bindaddress:绑定ip地址 dont_obey_robotstxt:不遵循反爬虫协议 download_timeout:下载超时
4.2.3. Request的子类FormRequest
FormRequest是Request的子类,通常用做表单数据提交。
FormRequest的构造: class scrapy.http.FormRequest(url[,formdata,...]) FormRequest类除了有Request的功能 还提供一个form_response()方法: form_response(response[,formname=None,formnumber=0,formdata=None,formxpath=None,clickdata=None,dont_click=False,...]) response:是指包含HTML表单的Response对象,该表单将用于预填充表单字段。 formname:若是给定,将使用设置为该值的name属性的表单。 formnumber:当响应包含多个表单时,要使用的表单的数量。 formnumber默认是0,表示使用第一个。 formdata:字段来覆盖表单数据。若是一个字段已经存在于响应<form>元素中,那么它的值被在这个参数中传递的值覆盖。 formxpath:若是给定,将使用与XPath匹配的第一个表单。 clickdata:查找单击控件的属性。若是没有给出,表单数据将被提交模拟点击第一个可点击的元素。 dont_click:若是为True,表单数据将被提交而不须要单击任何元素。
HTTP请求返回的响应对象,它一般被下载(由Downloader)下载并被传送给Spider进行处理。
4.3.1. 构造函数
class scrapy.http.Response(url[,status=200,headers,body,flags]) url:响应对象response的url headers:响应对象的响应报头 status:响应的状态码,默认200。 body:响应体 meta:为response.meta属性的初始值。若是给定的,字典将浅复制。 flags:是一个列表包含的response.flags初始值的属性。若是给定,列表将被浅拷贝。
TextResponse
TextResponse对象增长了编码能力的基础响应类,是指将只用于二进制数据,如图像、声音或任何媒体文件。
4.3.2 发送FormRequest表单请求
FormRequest新增长了一个参数formdata,接受包含表单数据的字典或者可迭代的元组,并将其转化为请求的body。而且FormRequest是继承Request的
# 发送FormRequest表单请求 return FormRequest.from_response(response=response, meta={'cookiejar': response.meta['cookiejar']}, headers=self.post_headers, formdata={ "utf8": utf8, "authenticity_token": authenticity_token, "login": login, "password": password, "commit": commit }, callback=self.after_login)
案例
有时候须要解析页面嵌套,能够采用callback, 解析页面page1,经过解析页面page2解析另外一个url
parse_page1 由url1产生response
def parse_page1(self, response): item = MyItem() item['main_url'] = response.url request = scrapy.Request("http://www.example.com/some_page.html", callback=self.parse_page2) request.meta['item'] = item yield request #将request对象发送到scheduler里面 中间要通过(request --> scheduler --> engine --> downloader --> engine --> spiders(response)) def parse_page2(self, response): item = response.meta['item'] item['other_url'] = response.url return item #将item结果数据发送到pipeline里面去 结果数据 item --> pipeline