• 欢迎来到本博客,希望可以y一起学习与分享

scrapy框架爬虫简单入门(三)–爬取知乎

Python benz 3年前 (2018-10-05) 68次浏览 0个评论 扫描二维码
文章目录[隐藏]

前言

知乎网站爬虫,有一个需要登录的流程。关于这种需要登录的网站,需要具备COOKIE、SESSION、HTTPCODE等网站网络的基本概念原理。

观察登录界面

在浏览器上,按F12,调出调试工具,观察登录界面,获取登录的请求地址以及所需的参数。通过输入错误的账号密码,我们可以找到登录请求的网址:

需要提交的表单数据为:

其中,参数“_xsrf”的值在网页的位置:

使用Requests库,模拟登录

使用pip install requests安装requests。我在utils文件夹中,创建模拟登录知乎的文件:zhihu_login_requests.py。在这个文件里编写登录流程。

引入相关库

因为基于Requests的模拟登录,所以,需要导入requests:import requests;登录流程必定涉及到cookies,所以引入cookies:import http.cookiejar as cookielib(这是python3的引入);还需要正则匹配,导入re库:import re

登录流程

请求参数,还需要“_xsrf”的值,我通过定义方法:get_xsrf() 去获取到“_xsrf”的值。

获取_xsrf的值

这里,通过requests去get方式请求网址,但是,需要携带请求头信息,去通过网站的校验。因此,需要定义请求头信息。

定义header请求头信息

有些网站,不添加请求头,服务器会返回错误码为500的页面。

模拟登陆

这样可以模拟提交表单数据,但是,登录后,如何接收cookies,并在此后的请求中携带这个cookies。解决这个问题,需要使用requests的session去做请求,而不是requests.

登录并保存cookies

实例化requests的session,使用session代替requests:session = requests.session()

session.cookies.save()把cookies保存到本地,还需要session.cookies实例化一个方法:session.cookies = cookielib.LWPCookieJar(filename='cookies.txt'),其中,filename为保存的cookies文件名。
cookies的保存有两个参数:
ignore_discard的意思是即使cookies将被丢弃也将它保存下来;
ignore_expires的意思是如果cookies已经过期也将它保存并且文件已存在时将覆盖。

携带cookies维持登录状态

执行登录

执行zhihu_login(账号,密码)这个方法即可登录。

验证是否登录成功

验证是否登录成功,可以单独用一个方法去下载首页网页到本地。打开保存到本地的静态网页,如果有登录人的信息就认为登录成功。

验证cookies是否过期

cookies是有过期时间的,我做一个判断cookies是否过期的方法。

人工获取验证码

这里是获取验证码的思路是,保存验证码到本地,打开验证码查看,input()手动输入看到的验证码,从而获取到验证码的值。这里并没采用图片识别来获取验证码,图片识别来获取验证码在以后的文章会说到。

这里,新建get_captcha()方法,来实现获取验证码的思路。验证码的请求地址有个可变的参数,把它变成占位,并通过format()方法去动态填充;验证码的请求要使用session来请求,因为session里携带了cookies信息,尽管session是属于request,但使用request来请求会失败,是因为request没有携带cookies;图片的处理操作需要安装pillow库:pip install pillow;最后通过input()接收手动输入的验证码来取得验证码的值。在登录参数里,把登录码补全:

zhihu_login_requests.py 完整代码

使用scrapy模拟登录(异步)

使用scrapy创建爬虫模板:scrapy genspider zhihu www.zhihu.com

导入文件

在创建好的爬虫模板zhihu.py里,除了导入scrapy外:import scrapy,如果需要正则匹配,还要导入re:import re

重写scrapy.Spider的爬虫入口

任何的爬虫模板,都会继承scrapy.Spider。在爬虫开始的时候,会先执行scrapy.Spider里的start_requests()方法。对于知乎这类需要登录的网站,则要求在爬虫开始工作的时候,完成网站的登录操作。所以,需要重写start_requests()方法,完成网站登录操作。

使用scrapy.FormRequest提交表单数据

scrapy提供了scrapy.FormRequest()来提交表单数据。

scrapy.FormRequest(url,formdata, headers,callback )的参数有:
url:提交的地址;
formdata:提交的数据;
headers:携带header请求头信息;
callback :回调方法,FormRequest提交数据后会把结果传给回调方法,进行下一步的处理;

scrapy.Request获取“_xsrf”的值

获取“_xsrf”的值,需要先获取网页的内容,然后通过正则匹配获取“_xsrf”的值。这里使用scrapy.Request()获取网页的内容,然后提取出“_xsrf”的值。

这里start_requests(self)里只有获取网页内容的一行代码return [scrapy.Request('https://www.zhihu.com', headers= self.header, callback=self.login)],而登录逻辑都移到了自定义的login方法,是因为scrapy.Request里有个回调函数,需要有个方法处理这些获取到的数据。而处理这个网页数据获取到“_xsrf”的值,与登录流程是相关的,所以写一起。

定义header头信息

表单提交结果的回调处理

scrapy.FormRequest有个回调函数,用于处理表单提交后的操作。

获取验证码与确保cookies的一致

scrapy是一个异步框架,scrapy.Request会异步处理多个请求,虽然,scrapy.Request也会自动携带cookies,但是如果直接调用scrapy.Request去请求网址,那么所携带的cookies是其他请求过的cookies。那么如何确保cookies的一致性呢?解决办法是:使用scrapy.Request里的callback=回调方法。通过回调方法,scrapy.Request可以把当前请求的数据包括cookies传递到回调方法的response里,使scrapy.Requestcallback=里的回调方法的cookies保持一致。

爬虫的时候禁止读取robots.txt

读取robots.txt会影响爬虫,因为robots.txt里会写有一些规则,某些网址不要爬取。如果爬虫遵循这个规则,会影响爬虫的数据爬取。所以,在settings.py里把ROBOTSTXT_OBEY = True改为False即可不读取robots.txt。

在入口文件加入运行命令

之前说了,scrapy的爬虫文件是不能直接运行的,需要scrapy命令行才能运行,所以到入口文件,添加:execute(['scrapy','crawl','zhihu'])即可。

爬取逻辑处理

登录成功后,就会调用def parse(self, response)方法来开始爬取逻辑的处理。这个思路是:提取出HTML页面中的所有URL,并跟踪这些URL进一步爬取,如果提取的URL中格式为:question/xxx 就下载之后进入解析函数。

其中,提取到question页面后,的回调函数parse_question,用于从question 页面中提取出具体的 item。

处理question页面的回调函数

爬取问题的答案(当前爬虫下,新建另一个爬虫)

上面说到, 爬取question的answer, 因为answer有独立的请求地址,获取answer相当于一次独立的爬虫,但是,相比一个爬虫的初始化条件,缺少一个类似start_url的初始爬虫地址列表,所以需要自定义一个初始爬虫地址列表。 start_answer_url 是answer页面的一个自定义初始爬虫地址列表。 由于answer的地址有可变参数,所以,使用占位符代替可变参数,并使用format()方法动态赋值。

处理answer页面的回调函数

数据存储的小技巧

在pipelines.py的MySQL数据库插入,其实需要改动的代码只有SQL语句,但是需要写许多item字段。

我们可以把这些item的赋值移到items.py里完成,并统一管理,pipelines.py里的只需优雅的写两行代码就行。

items的定义

其他地方的代码:
settings.py

utils文件夹里的common.py

只更新需要的字段

insert into 表(字段) values(值) on DUPLICATE key update content=values (content),只更新content字段

完整代码

zhihu.py

item.py

pipelines.py

zhihu_login_requests.py


文章 scrapy框架爬虫简单入门(三)–爬取知乎 转载需要注明出处
喜欢 (0)

您必须 登录 才能发表评论!