投稿    登录
  《Python3网络爬虫开发实战》赠书活动正在进行中!详情请戳赠书活动!欢迎参与!非常感谢!

小白进阶之Scrapy第一篇

Python 哎哟卧槽 253122浏览 138评论

这博文写得我懒癌犯了,最后的那个章节内容排序,我没有实验是否是正确的,不过这只是个教大家用Scrapy的教程,正确与否并不重要···  如果不正确,记得留言;等我懒癌过了,我再改改······

还有其它的问题也是一样··· ,把问题留言下; 等我懒癌过了·· 我改回来!嗯!是等我懒癌结束了,再改。

 

前面几篇博文,给大家从头到尾做了一个比较高效的爬虫,从这篇起来说说Python的爬虫框架Scrapy;

至于为什么要说框架呢?因为啊,框架可以帮我们处理一部分事情,比如下载模块不用我们自己写了,我们只需专注于提取数据就好了;

最重要的一点啊!框架使用了异步的模式;可以加快我们的下载速度,而不用自己去实现异步框架;毕竟实现异步爬虫是一件比较麻烦的事情。

不过啊!反爬虫这个坎还是要我们自己迈过去啊!这是后话,以后再说。我们先来让Scrapy能跑起来,并提取出我们需要的数据,再解决其它问题。

官方文档在这儿:点我

9555112

环境搭建:

关于这一点,对在Windows环境下使用的小伙伴来说,请务必使用我之前提到的 Anaconda 这个Python的发行版本,不然光环境的各种报错就能消磨掉你所有的学习兴趣!

下载地址在这儿:http://pan.baidu.com/s/1pLgySav

安装完成之后,在cmd中执行:conda install Scrapy     (如果需要使用特定版本,请在Scrapy后面加上 ==XXXX    XXXX代表你需要的版本号)

下面是安装示意图:

安装Scrapy

So Easy@@!环境搭建完成!是不是超简单?全程无痛啊!

下面开始踏上新的征程!Go Go Go!!

使用Scrapy第一步:创建项目;CMD进入你需要放置项目的目录  输入:

创建项目

OK项目创建完成。现在可以开始我们的爬取之旅了!      下面是目录中各个文件的作用

各个文件的作用

好了,目录我们认识完了,在开始之前给大家一个小技巧,Scrapy默认是不能在IDE中调试的,我们在根目录中新建一个py文件叫:entrypoint.py;在里面写入以下内容:

注意!第二行中代码中的前两个参数是不变的,第三个参数请使用自己的spider的名字。稍后我会讲到!!

现在整个目录看起来是这样:

快捷启动

基础工作准备完毕!我们来说说基本思路。

上面的准备工作完成之后,我们先不要着急开始工作,毕竟作为一个框架,还是很复杂的;贸然上手 开整,很容易陷入懵逼状态啊!一团浆糊,理不清思路,后面的事情做起来很很麻烦啦!

我们来看看下面这张图:

scrapy_architecture

这就是整个Scrapy的架构图了;

Scrapy Engine: 这是引擎,负责Spiders、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等等!(像不像人的身体?)

Scheduler(调度器): 它负责接受引擎发送过来的requests请求,并按照一定的方式进行整理排列,入队、并等待Scrapy Engine(引擎)来请求时,交给引擎。

Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spiders来处理,

Spiders:它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器),

Item Pipeline:它负责处理Spiders中获取到的Item,并进行处理,比如去重,持久化存储(存数据库,写入文件,总之就是保存数据用的)

Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件

Spider Middlewares(Spider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spiders中间‘通信‘的功能组件(比如进入Spiders的Responses;和从Spiders出去的Requests)

 

数据在整个Scrapy的流向:

程序运行的时候,

引擎:Hi!Spider, 你要处理哪一个网站?

Spiders:我要处理23wx.com

引擎:你把第一个需要的处理的URL给我吧。

Spiders:给你第一个URL是XXXXXXX.com

引擎:Hi!调度器,我这有request你帮我排序入队一下。

调度器:好的,正在处理你等一下。

引擎:Hi!调度器,把你处理好的request给我,

调度器:给你,这是我处理好的request

引擎:Hi!下载器,你按照下载中间件的设置帮我下载一下这个request

下载器:好的!给你,这是下载好的东西。(如果失败:不好意思,这个request下载失败,然后引擎告诉调度器,这个request下载失败了,你记录一下,我们待会儿再下载。)

引擎:Hi!Spiders,这是下载好的东西,并且已经按照Spider中间件处理过了,你处理一下(注意!这儿responses默认是交给def parse这个函数处理的

Spiders:(处理完毕数据之后对于需要跟进的URL),Hi!引擎,这是我需要跟进的URL,将它的responses交给函数 def  xxxx(self, responses)处理。还有这是我获取到的Item。

引擎:Hi !Item Pipeline 我这儿有个item你帮我处理一下!调度器!这是我需要的URL你帮我处理下。然后从第四步开始循环,直到获取到你需要的信息,

注意!只有当调度器中不存在任何request了,整个程序才会停止,(也就是说,对于下载失败的URL,Scrapy会重新下载。)

以上就是Scrapy整个流程了。

QQ图片20161022193315

大家将就着看看。

建立一个项目之后:

第一件事情是在items.py文件中定义一些字段,这些字段用来临时存储你需要保存的数据。方便后面保存数据到其他地方,比如数据库 或者 本地文本之类的。

第二件事情在spiders文件夹中编写自己的爬虫

第三件事情在pipelines.py中存储自己的数据

还有一件事情,不是非做不可的,就settings.py文件 并不是一定要编辑的,只有有需要的时候才会编辑。

建议一点:在大家调试的时候建议大家在settings.py中取消下面几行的注释:

设置setting01

这几行注释的作用是,Scrapy会缓存你有的Requests!当你再次请求时,如果存在缓存文档则返回缓存文档,而不是去网站请求,这样既加快了本地调试速度,也减轻了 网站的压力。一举多得

第一步定义字段:

好了,我们来做 第一步 定义一些字段;那具体我们要定义那些字段呢?

这个根据自己需要的提取的内容来定义。

比如:我们爬取小说站点都需要提取些什么数据啊?

小说名字、作者、小说地址、连载状态、连载字数、文章类别

就像下面这样:

Scrapy01

这样我们第一步就完成啦!是不是So Easy?ヾ(´▽‘)ノ ; 下面开始重点了哦!编写spider(就是我们用来提取数据的爬虫了)

第二步编写Spider:

在spiders文件中新建一个dingdian.py文件

并导入我们需用的模块

Scrapy02

PS:Scrapy中Response可以直接使用Xpath来解析数据;不过大家也可以使用自己习惯的包,比如我导入的BS4 、re ;当然也可以使其他比如pyquery之类的。这个并没有什么限制

另外或许个别小伙伴会遇到 from dingdian.items import DingdianItem这个导入失败的情况;可以试试把项目文件移动到根目录。

Request这个模块可以用来重写单独请求一个URL,用于我们后面跟进URL。

好了开整;首先我们需要什么?

我们需要从一个地址入手开始爬取,我在顶点小说上没有发现有全站小说地址,但是我找到每个分类地址全部小说:

玄幻魔幻:http://www.23wx.com/class/1_1.html

武侠修真:http://www.23wx.com/class/2_1.html

都市言情:http://www.23wx.com/class/3_1.html

历史军事:http://www.23wx.com/class/4_1.html

侦探推理:http://www.23wx.com/class/5_1.html

网游动漫:http://www.23wx.com/class/6_1.html

科幻小说:http://www.23wx.com/class/7_1.html

恐怖灵异:http://www.23wx.com/class/8_1.html

散文诗词:http://www.23wx.com/class/9_1.html

其他:http://www.23wx.com/class/10_1.html

全本:http://www.23wx.com/quanben/1

好啦!入口地址我们找到了,现在开始写第一部分代码:

当然对于上面的地址,我们是可以直接全使用Start_urls这种列表全部请求,不过并不太美观,我需要把其中,有规律的部分,单独其他方式实现,比如字典之类的:

Scrapy22

第十行:首先我们创建一个类 Myspider;这个类继承自scrapy.Spider(当然还有一些其他父类,继承各个父类后能实现的功能不一样);

第十二行:我们定义name:dingdian (请注意,这name就是我们在entrypoint.py文件中的第三个参数!)!!!!请务必注意:此Name的!名字!在整个项目中有且只能有一个、名字不可重复!!!!

第十一行:我们定义了一个allowed_domains;这个不是必须的;但是在某写情况下需要用得到,比如使用爬取规则的时候就需要了;它的作用是只会跟进存在于allowed_domains中的URL。不存在的URL会被忽略。

第十七行到第十九行:我们使用字符串拼接的方式实现了我们上面发现的全部URL。

第二十行和二十一行:我们使用了导入的Request包,来跟进我们的URL(并将返回的response作为参数传递给self.parse, 嗯!这个叫回调函数!)

第二十三行:使用parse函数接受上面request获取到的response。(请务必注意:不要轻易改写parse函数(意思就是不要把parse函数用作它用);因为这样request的回调函数被你用了,就没谁接受request返回的response啦!如果你非要用作它用,则需要自己给request一个回调函数哦!)

我们测试一下是否正常工作:在IDE中运行我们之前创建的entrypoint.py文件(如果没有这个文件是不能在IDE中运行的哦!ヽ(=^・ω・^=)丿)

然后会像这样:

Spider编写03

你会发现在红色状态报告之后,所有页面几乎是一瞬间出现的;那是因为Scrapy使用了异步啦!ヽ(°◇° )ノ

另外因为Scrapy遵循了robots规则,如果你想要获取的页面在robots中被禁止了,Scrapy是会忽略掉的哦!!ヾ(。 ̄□ ̄)ツ゜゜゜

请求就这么轻而易举的实现了啊!简直So Easy!

继续 继续!

我们需要历遍所有页面才能取得所有的小说页面连接:

分析网页2

分析网页01

每个页面的这个位置都是最后一个页面,我们提取出它,历遍就可以拼接出一个完整的URL了ヾ§  ̄▽)ゞ2333333

Go Go

Scrapy20

第二十三行:def parse(self, response)这个函数接受来在二十一行返回的response,并处理。

第二十四行:我们使用BS4从response中获取到了最大页码。

第二十五行至二十七行:我们照例拼接了一个完整的URL(response.url:就是这个response的URL地址)

第二十八行:功能和第二十行一样,callback=  是指定回调函数,不过不写callback=也没有什么影响! 注意我只是说的callback=这个几个;不是后面的self.get_name.

看清楚了response是怎么用的没?ヾ§  ̄▽)ゞ2333333是不是So Easy?

如果不清楚那个拼接URL的小伙伴可以打印出来,看看哦··· 再去观察一下网页,就很明白啦

 

上面两个函数就彻底的把整个网站的所有小说的页面URL的提取出来了,并将每个页面的response交给了get_name函数处理哦!

现在我们的爬虫就开始处理具体的小说了哦:

Scrapy07

 

瞅见没 我们需要的东西,快用F12工具看一下吧,在什么位置有什么标签,可以方便我们提取数据。还不知道怎么看的小伙伴,去看看妹子图那个教程,有教哦;实在不行百度一下也行!

过程忽略了,直接上代码(主要是懒癌来了):

Scrapy09

前面三行不说了,

第三十七和三十八行:是我们的小说名字和URL

第三十九行和第四十行;大伙儿可能会发现,多了个一个meta这么一个字典,这是Scrapy中传递额外数据的方法。因我们还有一些其他内容需要在下一个页面中才能获取到。

 

转载请注明:静觅 » 小白进阶之Scrapy第一篇

喜欢 (297)or分享 (0)

想学更多爬虫知识?《Python3网络爬虫开发实战》这本书也许更适合你~

了解详情or立即购买

我的个人微信公众号

扫码或搜索:进击的Coder

进击的Coder

微信公众号 扫一扫关注

想结交更多的朋友吗?

来进击的Coder瞧瞧吧

进击的Coder

QQ群号 99350970 立即加入

进击的Coder灌水太多?

这里是纯粹的技术领地

激进的Coder

QQ群号 627725766 立即加入

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请狠狠点击下面的

发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(138)个小伙伴在吐槽
  1. Woah! I'm really enjoying the template/theme of this website. It's simple, yet effective. A lot of times it's difficult to get that "perfect balance" between user friendliness and visual appearance. I must say you've done a very good job with this. Also, the blog loads extremely quick for me on Internet explorer. Excellent Blog!
    minecraft2018-10-07 14:20 回复
  2. I do believe all of the ideas you have offered to your post. They're very convincing and will certainly work. Still, the posts are very brief for beginners. Could you please lengthen them a little from next time? Thanks for the post.
    minecraft2018-10-06 19:31 回复
  3. Thanks for sharing your thoughts on python. Regards
    minecraft2018-10-06 00:52 回复
  4. 插入数据时候,汉字或者字母不能插入
    powers2018-08-31 13:26 回复
  5. 大神,为什么我的“from diangdian.items import DingdianItem”把dingdian.py移动根目录还是导入失败
    albey2018-07-24 21:04 回复
    • 有方法可以解决的
      风清扬2018-07-30 16:41 回复
    • 有方法可以解决的,https://zhuanlan.zhihu.com/p/40823390
      fengqingyang2018-07-30 16:42 回复
    • Pycharm中选中项目文件夹,右键 Mark Directory as - sources Root,再试一下
      北极鱼星2018-08-05 15:21 回复
  6. 你在写什么?能把完整代码在结尾处贴出来不
    无知的人类2018-07-21 22:18 回复
1 4 5 6