其实拿这个网站当教程刚开始我是拒绝、换其他网站吧,又没什么动力···· 然后就··········· 上一篇 Scrapy 带大家玩了 Spider 今天带带大家玩的东西有两点、第一 CrawlSpider、第二 Scrapy 登录。 目标站点:www.haoduofuli.wang Go Go Go!开整! 还记得第一步要干啥? 创建项目文件啊!没有 Scrapy 环境的小伙伴们请参考第一篇安装一下环境哦! 打开你的命令行界面(Windows 是 CMD)使用切换目录的命令到你需要的存放项目文件的磁盘目录
1 |
D: |
好了 我在 D 盘创建了一个叫做 haoduofuli 的项目。 用 Pycharm 打开这个目录开始我们的爬取之路 Come on! 下一步我们该做什么记得吧?当然是在 items.py 中声明字段了!方便我们在 Spider 中保存获取的内容并通过 Pipline 进行保存(items.py 本质上是一个 dict 字典) 我在 items.py 中声明了以下类容:
1 |
# -*- coding: utf-8 -*- |
至于为啥声明的这些类容:各位自己去网站上观察一下、(主要是吧,贴在这儿的话 估计这博文就要被人道主义销毁了) 别忘记上一篇博文教大家的那种在 IDE 中运行 Scrapy 的方法哦! 好上面的我们搞定、开始下一步编写 Spider 啦! 在 spiders 文件夹中新建一个文件 haoduofuli.py(还不清楚目录和作用的小哥儿快去看看 Scrapy 的第一篇) 首先导入以下包:
1 |
from scrapy.spiders import CrawlSpider, Rule, Request ##CrawlSpider与Rule配合使用可以骑到历遍全站的作用、Request干啥的我就不解释了 |
详细介绍请参考:http://scrapy-chs.readthedocs.io/zh_CN/latest/topics/spiders.html 中的:CrawlSpider、爬取规则(Crawling rules)、pare_start_url(response)|(此方法重写 start_urls)、以及 Spider 中 start_requests()方法的重写。 下面我带大家简单的玩玩儿顺便获取我们想要的东西。 前面提到了我们需要获取全站的资源、如果使用 Spider 的话就需要写大量的代码(当然只是相对而言的大量代码)!但是我们还有另一个选择那就是今天要说的 CrawlSpider! 首先我们新建一个函数 继承 CrawlSpider(上一篇博文是继承 Spider 哦!) 见证奇迹的时刻到了!
1 |
from scrapy.spiders import CrawlSpider, Rule, Request ##CrawlSpider与Rule配合使用可以骑到历遍全站的作用、Request干啥的我就不解释了 |
是不是很厉害!加上中间的空行也就不到二十行代码啊!就把整个网站历遍了!So Easy!! 上面的几行代码的意思 很明了了啊!我只说说 rules 这一块儿 表示所有 response 都会通过这个规则进行过滤匹配、匹配啥?当然是后缀为.html 的 URL 了、callback=’parseitem’表示将获取到的 response 交给 parse_item 函数处理(这儿要注意了、不要使用 parse 函数、因为 CrawlSpider 使用的 parse 来实现逻辑、如果你使用了 parse 函数、CrawlSpider 会运行失败。)、follow=True 表示跟进匹配到的 URL(顺便说一句 allow 的参数支持正则表达式、虽然我也用得不熟、不过超级好使) 至于我这儿的 allow 的参数为啥是’.\html’;大伙儿自己观察一下我们需要获取想要信息的页面的 URL 是不是都是以.html 结束的?明白了吧! 然后 rules 的大概运作方式是下面这样: 图很清晰明了了(本人也是初学、如有错误 还请各位及时留言 我好纠正。)中间的数据流向是靠引擎来完成的。 好了 我们来看看效果如何: 这是我们返回 response 的 URL、一水儿的 URL 啊!完美!下面就可以进行提取数据了(诶!不对啊怎么没有没什么提取工具啊!还记得上篇博文说的不?下载器返回的 response 是支持 Xpath 的哦!我们直接使用 Xpath 来提取数据就行啦!) 那么问题来了!Xpath 没用过啊!不会用啊!这可咋整啊!别怕!草鸡简单的!!来不着急! 先大声跟我念:Google 大法好啊! 哈哈哈 没错、我们需要 Chrome(至于为啥不用 Firefox、因为不知道为啥 Firefox 的 Xpath 有时和 Chrome 的结构不一样 有些时候提取不到数据、Chrome 则没什么问题) 来来!跟着我的节奏来!包你五分钟学会使用 Xpath!学不会也没关系、毕竟你也不能顺着网线来打我啊! 第一步:打开你的 Chrome 浏览器 挑选上面任意一个 URL 打开进入我们提取数据的页面(不贴图 容易被 Say GoogBay): 第二步:打开 Chrome 的调试模式找到我们需要提取的内容(如何快速找到呢?还不知道的小哥儿 我只能说你实在是太水了) 点击下面红圈的箭头 然后去网页上点击你需要的内容就 哔!的一下跳过去了! 第三步:在跳转的那一行就是你想要提取内容的一行(背景色完全区别于其它行!!)右键 Copy ——Copy XPath: 就像下面我提取标题: 你会得到这样的内容: //[@id=”postcontent”]/p[1] 意思是:在根节点下面的有一个 id 为 post_content 的标签里面的第一个 p 标签(p[1]) 如果你需要提取的是这个标签的文本你需要在后面加点东西变成下面这样: //[@id=”post_content”]/p[1]/text() 后面加上 text()标签就是提取文本 如果要提取标签里面的属性就把 text()换成@属性比如: //*[@id=”post_content”]/p[1]/@src So Easy!XPath 提取完毕!来看看怎么用的!那就更简单了!!!! response.xpath(‘你 Copy 的 XPath’).extract()[‘要取第几个值’] 注意 XPath 提取出来的默认是 List。 看完上面这一段 估计还没有五分钟吧 !好了 XPath 掌握了!我们来开始取我们想要的东西吧!现在我们的代码应该变成这样了:
1 |
from scrapy.spiders import CrawlSpider, Rule, Request ##CrawlSpider与Rule配合使用可以骑到历遍全站的作用、Request干啥的我就不解释了 |
我们来跑一下!简直完美! 关于 imgurl 那个 XPath: 你先随便找一找图片的地址 Copy XPath 类似得到这样的: //[@id=”post_content”]/p[2]/img 你瞅瞅网页会发现每一个有几张图片 每张地址都在一个 p 标签下的 img 标签的 src 属性中 把这个 2 去掉变成: //[@id=”post_content”]/p/img 就变成了所有 p 标签下的 img 标签了!加上 /@src 后所有图片就获取到啦!(不加[0]是因为我们要所有的地址、加了 就只能获取一个了!) 关于 XPath 更多的用法与功能详解,建议大家去看看 w3cschool (^o^)/ 第一部分完工、开始第二部分的工作吧!登!录! 毕竟这些都不是我们要的重点!我们要的是资源 资源啊!能下载东西的地方!如果不是为了资源 那么爬虫将毫无意义(给工钱的另算)。 但是下载资源是隐藏的,需要登录才能看见(别找我要帐号、我也是借的别人的。) 我们先来看看这个网站是怎么登录的,使用 Firefox 打开www.haoduofuli.wang/login.php(为啥是Firefox、因为个人感觉Firefox的表单界面看起来很爽啊!哈哈哈) 打开页面之后开启调试模式(怎么开不说了)—开启持续日志(不然跳转之后没了) 然后选择网络—选中 html 和 XHR(这样页面类容就会少很多、又不会缺少我们需要的东西) 现在开始登录(顺手把记住登录也勾上)!调试窗口不要关啊!!!!登录完毕之后你会发现出现一些内容 我们找到其中方法为 post 的请求、然后选择 参数 就能看到我们需要的登录表单啦! 我划掉的是帐号密码、这个位置应该显示你的帐号密码(这是很简单的一个登录表单、不通用但是思路是一样的。)找到了我们想要的东西我们开始登录吧 首先要知道 Scrapy 登录是如何实现的? 借助于 FromRequests 这个包实现的(前面已经导入过了),下面开整。不需要太大的改动只需增加一些函数 就可以轻而易举的实现的登录。 将我们的 start_urls 中的地址换掉换成我们我们的登陆地址www.haoduofuli.wang/login.php变成这样:
1 |
from scrapy.spiders import CrawlSpider, Rule, Request ##CrawlSpider与Rule配合使用可以骑到历遍全站的作用、Request干啥的我就不解释了 |
那么问题来了!参考上面的流程图你会发现、这丫的没法登录表单没法写啊!start_urls 返回的 responses 就直接给 rules 进行处理了诶!我们需要一个什么方法来截断 start_urls 返回的 responses 方便我们把登录的表单提交上去!那么问题来了 !该用啥? 答案是:parse_start_url(response)这方法;此方法作用是当 start_url 返回 responses 时调用这个方法。官方解释如下: 然后呢?当然是构造表单并通过 FormRequests 提交了!所以我们的程序现在就应该变成这样子了:
1 |
from scrapy.spiders import CrawlSpider, Rule, Request ##CrawlSpider与Rule配合使用可以骑到历遍全站的作用、Request干啥的我就不解释了 |
最后一句的意思是提交表单 formdate 并将回调 after_login 函数处理后续内容(一般用来判断是否登录成功) 然后开始请求我们需要爬取的页面 现在就变成这样了!
1 |
from scrapy.spiders import CrawlSpider, Rule, Request ##CrawlSpider与Rule配合使用可以骑到历遍全站的作用、Request干啥的我就不解释了 |
return Request(lnk)就表示我们的开始页面了 至于为啥多了一个 try 判断;完全是因为 这站长不守规矩啊!有些页面不一样·····我能怎么办 我也很无奈啊! 都是被逼的。囧 好了!Spider 写完啦!但是我们的工作还没完!!!网站是靠什么知道这个 request 是否是登录用户发出的?答案是 Cookie! 所以我们需要 下载器 在下载网页之前在 request 中加入 Cookie 来向网站证明我们是登录用户身份;才能获取到需要登录才能查看的信息! 这个该怎么做?现在 Scrapy 的中间件派上用场了! 关于 Cookie 中间件参考:http://scrapy-chs.readthedocs.io/zh_CN/latest/topics/downloader-middleware.html#module-scrapy.contrib.downloadermiddleware.cookies 我们需要做的就是在 settings.py 中的 DOWNLOADER_MIDDLEWARES 开启这个中间件:scrapy.downloadermiddlewares.cookies.CookiesMiddleware 请注意!!!!!! 每一个中间件会对 request 进行操作、你所做的操作可能会依赖于前一个中间件、所以每个中间件的顺序就异常的重要。具体该设置多少请参考: http://scrapy-chs.readthedocs.io/zh_CN/latest/topics/settings.html#std:setting-DOWNLOADER_MIDDLEWARES_BASE 中的值设置!!这点务必注意···如果不清楚依赖关系 请按照上图的值设置。 从上面可以看出 Cookie 中间件的值为 700 、我们在 settings.py 设置也应该为 700 我注释掉的请无视掉!!! 做好这些以后 Scrapy 运作的整个流程大概就变成了下面这样:
1 |
return Request(lnk) 这一个请求也算作 初始URL 只不过 不是start_urls的返回response 所以不会调用parse_start_url函数哦! |
跑一下!效果杠杠滴!!!至于后面的数据持久化(如何保存数据、大家请自行解决哦!比毕竟上一篇博文讲过了、) 这种更适合使用 MongoDB 存储 超级简单好使。 至此本篇博文结束。 这个还有一个分布式的版本、现在不想写了··· 等年后再写吧。 另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。另外我真的一个资源都没看。