经过前面四章的学习,我们已经可以使用Requests库、Beautiful Soup库和Re库,编写基本的Python爬虫程序了。那么这一章就来学习一个专业的网络爬虫框架--Scrapy。没错,是框架,而不是像前面介绍的函数功能库。
Scrapy是一个快速、功能强大的网络爬虫框架。
可能大家还不太了解什么是框架,爬虫框架其实是实现爬虫功能的一个软件结构和功能组件的集合。
简而言之, Scrapy就是一个爬虫程序的半成品,可以帮助用户实现专业的网络爬虫。
使用Scrapy框架,不需要你编写大量的代码,Scrapy已经把大部分工作都做好了,允许你调用几句代码便自动生成爬虫程序,可以节省大量的时间。
当然,框架所生成的代码基本是一致的,如果遇到一些特定的爬虫任务时,就不如自己使用Requests库搭建来的方便了。
PyCharm安装
测试安装:
出现框架版本说明安装成功。
掌握Scrapy爬虫框架的结构是使用好Scrapy的重中之重!
先上图:
整个结构可以简单地概括为: “5+2”结构和3条数据流
5个主要模块(及功能):
(1)控制所有模块之间的数据流。
(2)可以根据条件触发事件。
(1)根据请求下载网页。
(1)对所有爬取请求进行调度管理。
(1)解析DOWNLOADER返回的响应--response。
(2)产生爬取项--scraped item。
(3)产生额外的爬取请求--request。
(1)以流水线方式处理SPIDER产生的爬取项。
(2)由一组操作顺序组成,类似流水线,每个操作是一个ITEM PIPELINES类型。
(3)清理、检查和查重爬取项中的HTML数据并将数据存储到数据库中。
2个中间键:
(1)对Engine、Scheler、Downloader之间进行用户可配置的控制。
(2)修改、丢弃、新增请求或响应。
(1)对请求和爬取项进行再处理。
(2)修改、丢弃、新增请求或爬取项。
3条数据流:
(1):图中数字 1-2
1:Engine从Spider处获得爬取请求--request。
2:Engine将爬取请求转发给Scheler,用于调度。
(2):图中数字 3-4-5-6
3:Engine从Scheler处获得下一个要爬取的请求。
4:Engine将爬取请求通过中间件发送给Downloader。
5:爬取网页后,Downloader形成响应--response,通过中间件发送给Engine。
6:Engine将收到的响应通过中间件发送给Spider处理。
(3):图中数字 7-8-9
7:Spider处理响应后产生爬取项--scraped item。
8:Engine将爬取项发送给Item Pipelines。
9:Engine将爬取请求发送给Scheler。
任务处理流程:从Spider的初始爬取请求开始爬取,Engine控制各模块数据流,不间断从Scheler处获得爬取请求,直至请求为空,最后到Item Pipelines存储数据结束。
作为用户,只需配置好Scrapy框架的Spider和Item Pipelines,也就是数据流的入口与出口,便可完成一个爬虫程序的搭建。Scrapy提供了简单的爬虫命令语句,帮助用户一键配置剩余文件,那我们便来看看有哪些好用的命令吧。
Scrapy采用命令行创建和运行爬虫
PyCharm打开Terminal,启动Scrapy:
Scrapy基本命令行格式:
具体常用命令如下:
下面用一个例子来学习一下命令的使用:
1.建立一个Scrapy爬虫工程,在已启动的Scrapy中继续输入:
执行该命令,系统会在PyCharm的工程文件中自动创建一个工程,命名为pythonDemo。
2.产生一个Scrapy爬虫,以教育部网站为例http://www.moe.gov.cn:
命令生成了一个名为demo的spider,并在Spiders目录下生成文件demo.py。
命令仅用于生成demo.py文件,该文件也可以手动生成。
观察一下demo.py文件:
3.配置产生的spider爬虫,也就是demo.py文件:
4.运行爬虫,爬取网页:
如果爬取成功,会发现在pythonDemo下多了一个t20210816_551472.html的文件,我们所爬取的网页内容都已经写入该文件了。
以上就是Scrapy框架的简单使用了。
Request对象表示一个HTTP请求,由Spider生成,由Downloader执行。
Response对象表示一个HTTP响应,由Downloader生成,有Spider处理。
Item对象表示一个从HTML页面中提取的信息内容,由Spider生成,由Item Pipelines处理。Item类似于字典类型,可以按照字典类型来操作。
2. 如何在scrapy框架下,用python实现爬虫自动跳转页面来抓去网页内容
Scrapy是一个用Python写的Crawler Framework,简单轻巧,并且非常方便。Scrapy使用Twisted这个异步网络库来处理网络通信,架构清晰,并且包含了各种中间件接口,可以灵活地完成各种需求。Scrapy整体架构如下图所示:
根据架构图介绍一下Scrapy中的各大组件及其功能:
Scrapy引擎(Engine):负责控制数据流在系统的所有组建中流动,并在相应动作发生触发事件。
调度器(Scheler):从引擎接收Request并将它们入队,以便之后引擎请求request时提供给引擎。
下载器(Downloader):负责获取页面数据并提供给引擎,而后提供给Spider。
Spider:Scrapy用户编写用于分析Response并提取Item(即获取到的Item)或额外跟进的URL的类。每个Spider负责处理一个特定(或一些网站)。
Item Pipeline:负责处理被Spider提取出来的Item。典型的处理有清理验证及持久化(例如存储到数据库中,这部分后面会介绍存储到MySQL中,其他的数据库类似)。
下载器中间件(Downloader middlewares):是在引擎即下载器之间的特定钩子(special hook),处理Downloader传递给引擎的Response。其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy功能(后面会介绍配置一些中间并激活,用以应对反爬虫)。
Spider中间件(Spider middlewares):是在引擎及Spider之间的特定钩子(special hook),处理Spider的输入(response)和输出(Items即Requests)。其提供了一个简便的机制,通过插入自定义的代码来扩展Scrapy功能。
3. python scrapy 怎么将爬取的内容写出
首先,安装Python,坑太多了,一个个爬。由于我是windows环境,没钱买mac, 在安装的时候遇到各种各样的问题,确实各种各样的依赖。安装教程不再赘述。如果在安装的过程中遇到 ERROR:需要windows c/c++问题,一般是由于缺少windows开发编译环境,晚上大多数教程是安装一个VisualStudio,太不靠谱了,事实上只要安装一个WindowsSDK就可以了。下面贴上我的爬虫代码:
爬虫主程序:
[python]view plain
#-*-coding:utf-8-*-
importscrapy
fromscrapy.httpimportRequest
fromzjf.FsmzItemsimportFsmzItem
fromscrapy.selectorimportSelector
#圈圈:情感生活
classMySpider(scrapy.Spider):
#爬虫名
name="MySpider"
#设定域名
allowed_domains=["nvsheng.com"]
#爬取地址
start_urls=[]
#flag
x=0
#爬取方法
defparse(self,response):
item=FsmzItem()
sel=Selector(response)
item['title']=sel.xpath('//h1/text()').extract()
item['text']=sel.xpath('//*[@class="content"]/p/text()').extract()
item['imags']=sel.xpath('//div[@id="content"]/p/a/img/@src|//div[@id="content"]/p/img/@src').extract()
ifMySpider.x==0:
page_list=MySpider.getUrl(self,response)
forpage_singleinpage_list:
yieldRequest(page_single)
MySpider.x+=1
yielditem
#init:动态传入参数
#命令行传参写法:scrapycrawlMySpider-astart_url="e_url"
def__init__(self,*args,**kwargs):
super(MySpider,self).__init__(*args,**kwargs)
self.start_urls=[kwargs.get('start_url')]
defgetUrl(self,response):
url_list=[]
select=Selector(response)
page_list_tmp=select.xpath('//div[@class="viewnewpages"]/a[not(@class="next")]/@href').extract()
forpage_tmpinpage_list_tmp:
ifpage_tmpnotinurl_list:
url_list.append("px/"+page_tmp)
returnurl_list
[python]view plain
#-*-coding:utf-8-*-
#Defineyouritempipelineshere
#
#Don'_PIPELINESsetting
fromzjfimportsettings
importjson,os,re,random
importurllib.request
importrequests,json
fromrequests_toolbelt.multipart.encoderimportMultipartEncoder
classMyPipeline(object):
flag=1
post_title=''
post_text=[]
post_text_imageUrl_list=[]
cs=[]
user_id=''
def__init__(self):
MyPipeline.user_id=MyPipeline.getRandomUser('37619,18441390,18441391')
#processthedata
defprocess_item(self,item,spider):
#获取随机user_id,模拟发帖
user_id=MyPipeline.user_id
#获取正文text_str_tmp
text=item['text']
text_str_tmp=""
forstrintext:
text_str_tmp=text_str_tmp+str
#print(text_str_tmp)
#获取标题
ifMyPipeline.flag==1:
title=item['title']
MyPipeline.post_title=MyPipeline.post_title+title[0]
#保存并上传图片
text_insert_pic=''
text_insert_pic_w=''
text_insert_pic_h=''
forimag_urlinitem['imags']:
img_name=imag_url.replace('/','').replace('.','').replace('|','').replace(':','')
pic_dir=settings.IMAGES_STORE+'%s.jpg'%(img_name)
urllib.request.urlretrieve(imag_url,pic_dir)
#图片上传,返回json
upload_img_result=MyPipeline.uploadImage(pic_dir,'image/jpeg')
#获取json中保存图片路径
text_insert_pic=upload_img_result['result']['image_url']
text_insert_pic_w=upload_img_result['result']['w']
text_insert_pic_h=upload_img_result['result']['h']
#拼接json
ifMyPipeline.flag==1:
cs_json={"c":text_str_tmp,"i":"","w":text_insert_pic_w,"h":text_insert_pic_h}
else:
cs_json={"c":text_str_tmp,"i":text_insert_pic,"w":text_insert_pic_w,"h":text_insert_pic_h}
MyPipeline.cs.append(cs_json)
MyPipeline.flag+=1
returnitem
#spider开启时被调用
defopen_spider(self,spider):
pass
#sipder关闭时被调用
defclose_spider(self,spider):
strcs=json.mps(MyPipeline.cs)
jsonData={"apisign":"","user_id":MyPipeline.user_id,"gid":30,"t":MyPipeline.post_title,"cs":strcs}
MyPipeline.uploadPost(jsonData)
#上传图片
defuploadImage(img_path,content_type):
"uploadImagefunctions"
#UPLOAD_IMG_URL="dpostimage"
UPLOAD_IMG_URL="oadpostimage"
#传图片
#imgPath='D:picshttp___img_nvsheng_com_uploads_allimg_170119_18-1f1191g440_jpg.jpg'
m=MultipartEncoder(
#fields={'user_id':'192323',
#'images':('filename',open(imgPath,'rb'),'image/JPEG')}
fields={'user_id':MyPipeline.user_id,
'apisign':'',
'image':('filename',open(img_path,'rb'),'image/jpeg')}
)
r=requests.post(UPLOAD_IMG_URL,data=m,headers={'Content-Type':m.content_type})
returnr.json()
defuploadPost(jsonData):
CREATE_POST_URL="hmagespost"
[python]view plain
reqPost=requests.post(CREATE_POST_URL,data=jsonData)
[python]view plain
defgetRandomUser(userStr):
user_list=[]
user_chooesd=''
foruser_idinstr(userStr).split(','):
user_list.append(user_id)
userId_idx=random.randint(1,len(user_list))
user_chooesd=user_list[userId_idx-1]
returnuser_chooesd
[python]view plain
#-*-coding:utf-8-*-
#
#
#Seedocumentationin:
importscrapy
classFsmzItem(scrapy.Item):
#:
#name=scrapy.Field()
title=scrapy.Field()
#tutor=scrapy.Field()
#strongText=scrapy.Field()
text=scrapy.Field()
imags=scrapy.Field()
这样就可以爬取aaa.com下的内容了
4. python中的scrapy是什么意思a
Scrapy英文意思是刮擦
被用来命名爬虫界知名的框架。
使用这个框架可以轻易实现常规网页采集。也支持大型架构。升级后redis更是支持分布式。利用scrapyd更是可以发布服务。
从事爬虫方向必学!
5. python爬虫怎么做
大到各类搜索引擎,小到日常数据采集,都离不开网络爬虫。爬虫的基本原理很简单,遍历网络中网页,抓取感兴趣的数据内容。这篇文章会从零开始介绍如何编写一个网络爬虫抓取数据做告宏,然后会一步步逐渐完善爬虫的抓取功能。
工具安装
我们需要安装python,python的requests和BeautifulSoup库。我们用Requests库用抓取网页的内容,使用BeautifulSoup库来从网页中提取数据。
安装python
运行pipinstallrequests
运行pipinstallBeautifulSoup
抓取网页
完成必要工具安装后,我们正式开始编写我们的爬虫。我们的第一个任务是要抓取所有豆瓣上的图书信息。我们以/subject/26986954/为例,首先看看开如何抓取网页的内容。
使用python的requests提供的get()方法我们可以非常简单的获取的指定网页的内纯册容,代码如下:
提取内容
抓取到网页的内容后,我们要做的就是提取出我们想要的内容。在我们的第一个例子中,我们只需要提取书名。首先我们导入BeautifulSoup库,使用BeautifulSoup我们可以非常简单的提取网页的特定内容。
连续抓取网页
到目前为止,我们已经可以抓取单个网页的内容了,现在让我们看看如何抓取整个网站的内容。我们知道网页之间是通过超链接互相连接在一起的,通过链接我们可以访问整个网络。所以我们可以从每个页面提取出包含指向其它网页的链接,然后重复的对新链接进行抓取。
通过以上几步我们就可以写出一个最原始的爬虫。在理解了爬虫原理的基础上,我们可以进一步对爬虫进行完善。
写过一个系列关于爬虫的文章:/i6567289381185389064/。感兴趣的可以前往查看。
Python基本环境的搭建,爬虫的基本原理以及爬虫的原型
Python爬虫入门(第1部分)
如何使用BeautifulSoup对网页内容进行提取
Python爬虫入门(第2部分)
爬虫运行时数据的存储数据,以SQLite和MySQL作为示例
Python爬虫入门(第3部分)
使用seleniumwebdriver对动态网页进行抓取
Python爬虫入门(第4部分)
讨论了如何处理网站的反爬虫策略
Python爬友如虫入门(第5部分)
对Python的Scrapy爬虫框架做了介绍,并简单的演示了如何在Scrapy下进行开发
Python爬虫入门(第6部分)
6. scrapy和python有什么关系
Scrapy是Python开发的一个快速、高层次的web数据抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘和监测。
Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、sitemap爬虫等。
Scrapy算得上是Python世界中最常用的爬虫框架了,同时它也是我掌握的几种流行语言中最好的爬虫框架,没有之一!我认为它也是最难学习的框架,同样没有之一。很多初学Scarpy的经常向我抱怨完全不清楚Scrapy该怎样入手,即使看的是中文的文档,也感到很难理解。我当初接触Scrapy时也有这样的感觉。之所以感到Scrapy难学,究其原因,是其官方文档实在太过凌乱,又缺少实用的代码例子,让人看得云里雾里,不知其所已然。虽然其文档不良,但却没有遮挡住它的光辉,它依然是Python世界中目前最好用的爬虫框架。其架构的思路、蜘蛛执行的效能,还有可扩展的能力都非常出众,再配以Python语言的简洁轻巧,使得爬虫的开发事半功倍。
相关推荐:《Python基础教程》
Scrapy的优点:
(1)提供了内置的HTTP缓存,以加速本地开发。
(2)提供了自动节演调节机制,而且具有遵守robots.txt的设置的能力。
(3)可以定义爬行深度的限制,以避免爬虫进入死循环链接。
(4)会自动保留会话。
(5)执行自动HTTP基本认证。不需要明确保存状态。
(6)可以自动填写登录表单。
(7)Scrapy有一个内置的中间件,可以自动设置请求中的引用(referrer)头。
(8)支持通过3xx响应重定向,也可以通过HTML元刷新。
(9)避免被网站使用的meta重定向困住,以检测没有JS支持的页面。
(10)默认使用CSS选择器或XPath编写解析器。
(11)可以通过Splash或任何其他技术(如Selenium)呈现JavaScript页面。
(12)拥有强大的社区支持和丰富的插件和扩展来扩展其功能。
(13)提供了通用的蜘蛛来抓取常见的格式:站点地图、CSV和XML。
(14)内置支持以多种格式(JSON、CSV、XML、JSON-lines)导出收集的数据并将其存在多个后端(FTP、S3、本地文件系统)中。
Scrapy框架原理
Scrapy Engine(引擎):负责Spider、ItemPipeline、Downloader、Scheler中间的通讯,信号、数据传递等。
Scheler(调度器):负责接收引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。
Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理,
Spider(爬虫):负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheler(调度器),
Item Pipeline(管道):负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方.
Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件。
Spider Middlewares(Spider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)
Scrapy各个组件介绍
·Scrapy Engine:
引擎负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。它也是程序的入口,可以通过scrapy指令方式在命令行启动,或普通编程方式实例化后调用start方法启动。
·调度器(Scheler)
调度器从引擎接收爬取请求(Request)并将它们入队,以便之后引擎请求它们时提供给引擎。一般来说,我们并不需要直接对调度器进行编程,它是由Scrapy主进程进行自动控制的。
·下载器(Down-loader)
下载器负责获取页面数据并提供给引擎,而后将网站的响应结果对象提供给蜘蛛(Spider)。具体点说,下载器负责处理产生最终发出的请求对象 Request 并将返回的响应生成 Response对象传递给蜘蛛。
·蜘蛛——Spiders
Spider是用户编写用于分析响应(Response)结果并从中提取Item(即获取的Item)或额外跟进的URL的类。每个Spider负责处理一个特定(或一些)网站。
·数据管道——Item Pipeline
Item Pipeline 负责处理被 Spider 提取出来的 Item。 典型的处理有清理、验证及持久化(例如,存取到数据库中)。
·下载器中间件(Downloader middle-wares)
下载器中间件是在引擎及下载器之间的特定钩子(specific hook),处理Downloader传递给引擎的Response。其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy的功能。
·Spider中间件(Spider middle-wares)
Spider 中间件是在引擎及 Spider 之间的特定钩子(specific hook),处理 Spider 的输入(Response)和输出(Items及Requests)。其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy的功能。
从Scrapy的系统架构可见,它将整个爬网过程进行了非常具体的细分,并接管了绝大多数复杂的工作,例如,产生请求和响应对象、控制爬虫的并发等。