python爬虫之Scrapy框架,基本介绍使用以及用框架下
一、Scrapy框架简介
Scrapy是:由Python语言开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据,只需要实现少量的代码,就能够快速的抓取。
Scrapy使用了Twisted异步网络框架来处理网络通信,可以加快我们的下载速度,不用自己去实现异步框架,并且包含了各种中间件接口,可以灵活地实现各种需求。
Scrapy可以应用在包括数据挖掘、信息处理或存储历史数据等一系列的程序中,其最初是为页面抓取(更确切地说是网络抓取)而设计的,也可以应用于获取API所返回的数据(例如AmazonAssociatesWebServices)或者通用的网络爬虫。二、Scrapy架构
1、架构图
官方架构图
翻译架构图
2、组件
Scrapy主要包括了以下组件:爬虫中间件(SpiderMiddleware):位于Scrapy引擎和爬虫之间的框架,主要用于处理爬虫的响应输入和请求输出。调度器中间件(SchedulerMiddleware):位于Scrapy引擎和调度器之间的框架,主要用于处理从Scrapy引擎发送到调度器的请求和响应。调度器(Scheduler):用来接收引擎发过来的请求,压入队列中,并在引擎再次请求的时候返回。它就像是一个URL的优先队列,由它来决定下一个要抓取的网址是什么,同时在这里会去除重复的网址。下载器中间件(DownloaderMiddleware):位于Scrapy引擎和下载器之间的框架,主要用于处理Scrapy引擎与下载器之间的请求及响应。代理IP和用户代理可以在这里设置。下载器(Downloader):用于下载网页内容,并将网页内容返回给爬虫。
Scrapy引擎(ScrapyEngine):用来控制整个系统的数据处理流程,并进行事务处理的触发。爬虫(Spiders):爬虫主要是干活的,用于从特定网页中提取自己需要的信息,即所谓的项目(又称实体)。也可以从中提取URL,让Scrapy继续爬取下一个页面。项目管道(Pipeline):负责处理爬虫从网页中爬取的项目,主要的功能就是持久化项目、验证项目的有效性、清除不需要的信息。当页面被爬虫解析后,将被送到项目管道,并经过几个特定的次序来处理其数据。
3、运行流程
数据流(Dataflow),Scrapy中的数据流由执行引擎(ScrapyEngine)控制,其过程如下:引擎打开一个网站(openadomain),找到处理该网站的Spider并向该spider请求第一个要爬取的URL(s)。引擎从Spider中获取到第一个要爬取的URL并在调度器(Scheduler)以Request调度。引擎向调度器请求下一个要爬取的URL。调度器返回下一个要爬取的URL给引擎,引擎将URL通过下载中间件(请求(request)方向)转发给下载器(Downloader)。一旦页面下载完毕,下载器生成一个该页面的Response,并将其通过下载中间件(返回(response)方向)发送给引擎。引擎从下载器中接收到Response并通过Spider中间件(输入方向)发送给Spider处理。Spider处理Response并返回爬取到的Item及(跟进的)新的Request给引擎。引擎将(Spider返回的)爬取到的Item给ItemPipeline,将(Spider返回的)Request给调度器。(从第二步)重复直到调度器中没有更多地request,引擎关闭该网站三、Scrapy安装以及生成项目
1、下载安装
Linux下载方式,直接安装pipinstallscrapy或者pip3installscrapy)
windows如果用Pycharm的话,在Pycharm底部打开命令终端
输入命令pipinstallscrapy
2、创建Scrapy项目创建一个叫ScrapyDemmoscrapystartprojectScrapyDemmo进入项目文件夹cdScrapyDemmo创建一个名为baidu的爬虫,爬虫目标www。baidu。comscrapygenspiderbaiduwww。baidu。com
创建完成后,目录结构如下:
scrapy。cfg:项目的配置文件。scrapyspider:该项目的python模块。之后您将在此加入代码。scrapyspideritems。py:项目中的item文件。scrapyspiderpipelines。py:项目中的pipelines文件。scrapyspidersettings。py:项目的设置文件。scrapyspiderspiders:放置spider代码的目录。
spiders下的baidu。py是scrapy用命令(scrapygenspiderbaiduwww。baidu。com)自动为我们生成的。
内容如下:importscrapyclassBaiduSpider(scrapy。Spider):namebaidualloweddomains〔www。baidu。com〕starturls〔http:www。baidu。com〕defparse(self,response):titleresponse。xpath(htmldeadtitletext())print(title)
当然,可以不用命令生成,可以自己在spiders下创建爬虫,您必须继承scrapy。Spider类,且定义以下三个属性:name:用于区别Spider。该名字必须是唯一的,您不可以为不同的Spider设定相同的名字。starturls:包含了Spider在启动时进行爬取的url列表。因此,第一个被获取到的页面将是其中之一。后续的URL则从初始的URL获取到的数据中提取。parse()是spider的一个方法。被调用时,每个初始URL完成下载后生成的Response对象将会作为唯一的参数传递给该函数。该方法负责解析返回的数据(responsedata),提取数据(生成item)以及生成需要进一步处理的URL的Request对象。
3、运行爬虫
运行方法:
在项目目录底下用命令运行,如下,我项目目录D:PythonScrapyDemmo,运行name为baidu的爬虫D:PythonScrapyDemmoscrapycrawlbaidu
在scrapy中,为了避免每一次运行或调试都输入一串命令,可以在项目文件下新建一个run。py文件,每次运行爬虫只需要运行此脚本即可。且运行调试模式也需要设置此启动脚本。fromscrapyimportcmdlinecmdline。execute(scrapycrawlbaidu。split())
最后运行这个run。py即可,执行结果:D:PythonvenvScriptspython。exeD:PythonScrapyDemmoScrapyDemmorun。py2022102810:12:55〔scrapy。utils。log〕INFO:Scrapy2。7。0started(bot:ScrapyDemmo)2022102810:12:55〔scrapy。utils。log〕INFO:Versions:lxml4。9。1。0,libxml22。9。12,cssselect1。1。0,parsel1。6。0,w3lib2。0。1,Twisted22。8。0,Python3。9。13(tagsv3。9。13:6de2ca5,May172022,16:36:42)〔MSCv。192964bit(AMD64)〕,pyOpenSSL22。1。0(OpenSSL3。0。55Jul2022),cryptography38。0。1,PlatformWindows1010。0。22000SP02022102810:12:55〔scrapy。crawler〕INFO:Overriddensettings:{BOTNAME:ScrapyDemmo,NEWSPIDERMODULE:ScrapyDemmo。spiders,REQUESTFINGERPRINTERIMPLEMENTATION:2。7,ROBOTSTXTOBEY:True,SPIDERMODULES:〔ScrapyDemmo。spiders〕,TWISTEDREACTOR:twisted。internet。asyncioreactor。AsyncioSelectorReactor}2022102810:12:55〔asyncio〕DEBUG:Usingselector:SelectSelector。。。。。。
若嫌弃scrapy日志文件太杂乱,想无日志输出,只需在后面增加nolog即可:fromscrapyimportcmdlinecmdline。execute(scrapycrawlbaidunolog。split())
执行导出为json或scv格式,执行爬虫文件时添加o选项即可
scrapycrawl项目名o。csv
scrapycrawl项目名o。json
对于json文件,在setting。js文件里添加,设置编码格式,否则会乱码:fromscrapyimportcmdlinecmdline。execute(scrapycrawlbaiduobaidu。csv。split())四、Scrapy配置文件settings。py
默认配置文件,主要设置参数:BOTNAMEScrapyDemmoScrapy项目的名字,这将用来构造默认UserAgent,同时也用来log,当您使用startproject命令创建项目时其也被自动赋值。SPIDERMODULES〔ScrapyDemmo。spiders〕Scrapy搜索spider的模块列表默认:〔xxx。spiders〕NEWSPIDERMODULEScrapyDemmo。spiders使用genspider命令创建新spider的模块。默认:xxx。spiders爬取的默认UserAgent,除非被覆盖USERAGENTScrapyDemmo(http:www。yourdomain。com)如果启用,Scrapy将会采用robots。txt策略ROBOTSTXTOBEYTrueScrapydownloader并发请求(concurrentrequests)的最大值,默认:16CONCURRENTREQUESTS32为同一网站的请求配置延迟(默认值:0)Seehttps:docs。scrapy。orgenlatesttopicssettings。htmldownloaddelaySeealsoautothrottlesettingsanddocsDOWNLOADDELAY3下载器在下载同一个网站下一个页面前需要等待的时间,该选项可以用来限制爬取速度,减轻服务器压力。同时也支持小数:0。25以秒为单位下载延迟设置只有一个有效CONCURRENTREQUESTSPERDOMAIN16对单个网站进行并发请求的最大值。CONCURRENTREQUESTSPERIP16对单个IP进行并发请求的最大值。如果非0,则忽略禁用Cookie(默认情况下启用)COOKIESENABLEDFalse禁用Telnet控制台(默认启用)TELNETCONSOLEENABLEDFalse覆盖默认请求标头:DEFAULTREQUESTHEADERS{Accept:texthtml,applicationxhtmlxml,applicationxml;q0。9,;q0。8,AcceptLanguage:en,}项目管道,300为优先级,越低越爬取的优先度越高Seehttps:docs。scrapy。orgenlatesttopicsitempipeline。htmlITEMPIPELINES{ScrapyDemmo。pipelines。ScrapydemmoPipeline:300,}
还可以设置日志的等级与日志存放的路径:
相关变量LOGLEVELLOGFILE日志名。log
日志等级分为,默认等级是1DEBUG调试信息INFO一般信息WARNING警告ERROR普通错误CRITICAL严重错误
如果设置
LOGLEVELWARNING,就只会WARNING等级之下的ERROR和CRITICAL
一般主要需要配置的几个参数,其他按需配置即可。
USERAGENT:默认是注释的,这个东西非常重要,如果不写很容易被判断为电脑爬虫。
ROBOTSTXTOBEY:是否遵循机器人协议,默认是true,需要改为false,否则很多东西爬不了
DEFAULTREQUESTHEADERS:和USERAGENT类似,只是参数更完整。五、完整案例(下载图片)
用scrapy框架下载以前的示例:python爬虫之批量下载图片
1、修改settings。py主要参数关闭robot。txt协议ROBOTSTXTOBEYFalse页面延迟下载,我这里测试,可以先不设置DOWNLOADDELAY1是否启用CookieCOOKIESENABLEDTrue请求头DEFAULTREQUESTHEADERS{Accept:texthtml,applicationxhtmlxml,applicationxml;q0。9,;q0。8,AcceptLanguage:en,UserAgent:Mozilla5。0(WindowsNT10。0;Win64;x64)AppleWebKit537。36(KHTML,likeGecko)Chrome106。0。0。0Safari537。36}打开下载器DOWNLOADERMIDDLEWARES{ScrapyDemmo。middlewares。ScrapydemmoDownloaderMiddleware:543,}打开优先级,并添加自己编写的图片下载管道ITEMPIPELINES{ScrapyDemmo。pipelines。ScrapydemmoPipeline:300,ScrapyDemmo。pipelines。ImageDownloadPipeline:300,}添加下载储存目录IMAGESSTORED:Pythonpic文件保存时间IMAGESEXPIRES90
2、定义Item字段(Items。py)
本项目用于下载图片,因此可以仅构建图片名和图片地址字段。importscrapyclassScrapydemmoItem(scrapy。Item):图片下载链接imageurlscrapy。Field()图片名称imagenamescrapy。Field()
3、编写爬虫文件(spiders目录下)
这里文件名为:imagedownload。py
以前用requests库和BeautifulSoup库下载图片,这里就不需要了,scrapy自带相关函数和方法。
scrapy元素定位,提供三种方式,正则、Xpath表达式、css。
我这里有xpath定位方式。importscrapyimportrefrom。。itemsimportScrapydemmoItemclassImageSpider(scrapy。Spider):nameimagedownloadalloweddomains〔desk。3gbizhi。com〕starturls〔https:desk。3gbizhi。comdeskMVindex。html〕defparse(self,response):导入Items。py字段itemsScrapydemmoItem()获取所有链接列表listsresponse。xpath(p〔5〕ulli)点位元素循环获取图片链接和图片名称foriinlists:图片名称imagenamei。xpath(。aimgalt)。get()图片链接items〔imageurl〕i。xpath(。aimg〔1〕)。get()。replace(。278。154。jpg,)图片格式类型imagetypere。sub(rh。d。,,items〔imageurl〕)拼接文件名,图片名称图片格式items〔imagename〕{}。{}。format(imagename,imagetype)yielditems循环跳转下一页,并重复返回数据,这里测试先下载1页的图片,总共23页。foriinrange(2,3):nexturlhttps:desk。3gbizhi。comdeskMVindex{}。html。format(i)yieldscrapy。Request(nexturl,callbackself。parse)
关于yield的理解,先,如果你还没有对yield有个初步分认识,那么你先把yield看做return,这个是直观的,它先是个return。
最主要的不同在于yield在返回值后还可以继续运行接下来的代码,使用的函数会返回一个生成器,而return在返回后就不在执行代码。
以上两个yield:yielditems:这里我们通过yield返回的不是Request对象,而是一个ScrapydemmoItem对象。scrap有框架获得这个对象之后,会将这个对象传递给pipelines。py来做进一步处理。我们将在pipelines。py里将传递过来的scrapy。Item对象保存到数据库里去。yieldscrapy。Request:这里是在爬取完一页的信息后,我们在当前页面获取到了下一页的链接,然后通过yield发起请求,并且将parse自己作为回调函数来处理下一页的响应。
4、修改管道文件pipelines。py用于下载图片
除了爬取文本,我们可能还需要下载文件、视频、图片、压缩包等,这也是一些常见的需求。scrapy提供了FilesPipeline和ImagesPipeline,专门用于下载普通文件及图片。
继承Scrapy内置的ImagesPipeline,只需要重写getmediarequests和itemcompleted函数即可。fromscrapy。pipelines。imagesimportImagesPipelinefromscrapy。exceptionsimportDropItemfromscrapyimportRequestclassScrapydemmoPipeline:defprocessitem(self,item,spider):returnitemclassImageDownloadPipeline(ImagesPipeline):defgetmediarequests(self,item,info):下载图片,如果传过来的是集合需要循环下载meta里面的数据是从spider获取,然后通过meta传递给下面方法:filepathyieldRequest(urlitem〔imageurl〕,meta{filename:item〔imagename〕})defitemcompleted(self,results,item,info):分析下载结果并剔除下载失败的图片imagepaths〔x〔path〕forok,xinresultsifok〕ifnotimagepaths:raiseDropItem(Itemcontainsnoimages)returnitemdeffilepath(self,request,responseNone,infoNone):接收上面meta传递过来的图片名称filenamerequest。meta〔filename〕returnfilenamegetmediarequests()。它的第一个参数item是爬取生成的Item对象。我们将它的url字段取出来,然后直接生成Request对象。此Request加入调度队列,等待被调度,执行下载。itemcompleted(),它是当单个Item完成下载时的处理方法。因为可能有个别图片未成功下载,所以需要分析下载结果并剔除下载失败的图片。该方法的第一个参数results就是该Item对应的下载结果,它是一个列表形式,列表每一个元素是一个元组,其中包含了下载成功或失败的信息。这里我们遍历下载结果找出所有成功的下载列表。如果列表为空,那么说明该Item对应的图片下载失败了,随即抛出异常DropItem,该Item忽略。否则返回该Item,说明此Item有效。
以上两个函数即可下载图片了,图片名称为自动已哈希值命名,如:0db6e07054d966513f0a6f315b687f205c7ced90。jpg这种命名方式不友好,所以我们需要重写filepath函数,自定义图片名称。filepath():它的第一个参数request就是当前下载对应的Request对象。这个方法用来返回保存的文件名,接收上面meta传递过来的图片名称,将图片以原来的名称和定义格式进行保存。
5、编写执行文件run。py运行
在项目下新建run。py作为执行文件fromscrapyimportcmdlinecmdline。execute(scrapycrawlimagedownloadnolog。split())cmdline。execute(scrapycrawlimagedownload。split())
运行此文件,执行结果,在目录下载第一页壁纸完成。
六、小结
除了ImagesPipeline处理图片外,还有FilesPipeline可以处理文件,使用方法与图片类似,事实上ImagesPipeline是FilesPipeline的子类,因为图片也是文件的一种。
Scrapy很强大,对于大型网站非常实用,还可以同时运行多个爬虫程序,提升效率。Scrapy还有很多功能,可以自己研究。
过年了想买点粮食酒,不要勾兑那种,有什么推荐?酒精分两种一种是食用酒精,另一种是工业用酒精。不勾兑的食用酒(头流)是不能饮用的,原因是酒精度太高,口味也不好。只能与三流酒勾兑。二流旳品质最隹,酒精度适中,口味也是最好的。不要误
当今世界斯诺克选手当中,你觉得谁最有可能超越奥沙利文?纵观当今斯诺克球坛,妄言1个世纪内都没人能超越奥沙利文。这是个能在斯诺克圣殿的铁王座上坐很久很久很久的男人,性格天赋技术成绩打法观赏性集于一身,随随便便就能干个147,你让人怎么去
静脉血糖和指检血糖有什么差别?哪个能更准确反应我们的血糖水平?查静脉血糖和手指血糖有什么差别?哪个查出来的结果更准确?这是许多糖尿病友都十分关心的问题。要理解这个问题的答案,必须从两个方面来讨论一手指血和静脉血血糖水平是一样的吗?1扎手指采血
iPhone7更换第三方大容量电池对手机有影响吗?感谢您的阅读!针对这个问题我询问了几家做电池的店铺。给我的答案都是不影响。并且给出了充足的理由手机大容量电池只是电池容量增加了,但是因为电池体积不变,所以手机没有影响。事实真的如此
湘军名将刘长佑曾提出一项灭亡日本计划,为何不被采纳?刘长佑提出灭亡日本的完整计划,如果当时能够顺利实施的话,中国的领土可能更大,世界上也可能少了一个国家。湖南人杰地灵出人才,而刘长佑就是其中一个,但可能很多人并不了解甚至不知道有这样
70岁尿酸多高正常?众所周知,尿酸升高以后是会引发痛风的,不仅如此,尿酸升高以后,还会增加很多疾病的风险,比如高血压,糖尿病,肾脏疾病,呼吸系统疾病,冠心病,心力衰竭,肥胖等等疾病。所以控制尿酸与控制
美联储鹰派言论不断,加息预期再升温,如何看待本次缩表的影响?谢邀!首先简答现在看来,美联储今年至少加息三次,可能四五次,最快三月(甚至二月)第一次,可能一下加息0。5!同时开始runoff(缩表)。至于影响,在之前回复美国通胀猛升,美联储何
未来三年,西安市的平均房价会降到1万以下吗?西安市的平均房价在未来三年可能会降到1万以下,为什么这么说呢?总结如下一西安市平均工资不高。一个城市的上班族工资水平如何,关系到他们的购买力幸福感获得感。2020年西安市私营企业就
还记得你们怀孕时有多矫情吗?我怀孕一点也不矫情,可以说是太皮实了。怀孕两个月的时候,医生说有点先兆性流产,让我请假休息,当时自己没当回事,也没请假,一直上班了,虽然没什么事,现在想想也觉得自己太冒险。然后就是
最感人的一部国产影片是哪部,你有没有因此而落泪?最近看了电影长津湖,剧中情景让我流泪更让我震撼。当年参加抗美援朝的那些志愿军,他们赴朝作战,在极寒严酷环境下,东线作战部队凭着钢铁意志和英勇无畏的战斗精神一路追击,奋勇杀敌,扭转了
如何能练到一拳可以击倒一个人?正常打沙袋正确坚持苦练3年,打没有防备的普通人基本一拳解决,打有防备或练过的只要时机把握好一样一拳解决。绝对力量,快速,准确的击打薄弱位置,如嘴围三角区,咽喉等部位。具体可以手持一