5.2 模拟登录网站
5.2.1 豆瓣网站的登录分析
现在假设目标是爬取豆瓣网站日月光华个人主页的动态信息,必须登录才能看到这些信息。如果想登录豆瓣网站,首先需要打开豆瓣的首页,然后在首页的登录框内填写用户名和密码,最后单击“登录豆瓣”完成登录的过程。为了让爬虫能够模拟这个登录豆瓣网站的过程,首先要做的是对登录过程进行分析,弄清楚填写的用户名和密码是如何被提交到网站服务器的。
在 Chrome 浏览器中打开豆瓣首页,可以看到在右上角有登录的输入框,现在在网页的空白处单击右键,在弹出的菜单中选择“检查”,这时候在网页下方(或右侧)弹出了检查页面。在检查页面顶部的菜单中选择 Network,如图 5-3 所示。
图 5-3 使用 Chrome 检查工具分析登录过程
Network 这一栏会记录网络请求情况,如登录、下载的链接详情等。现在输入用户名和密码,然后单击“登录豆瓣”。可以看到 Network 栏目下出现非常多的请求链接信息,把滚动条拉到最上面,能看到最开始请求的链接,Name 为 login。单击这个 login,右侧会显示 login 这个请求的 Headers 详细信息,如图 5-4 所示。
图 5-4 请求的 Headers 详细信息
由 General 这一项可知:请求的网址(Request URL)为 https://www.douban.com/accounts/login;请求方法(Request Method)为 POST。
这些信息说明,登录的过程实际上是向 https://www.douban.com/accounts/login 这个网址发起了 POST 请求。那么到底向服务器 POST 了什么数据呢?把滚动条拉动到最下面,可以看到系统到底 POST 了哪些数据到服务器,如图 5-5 所示。Form Data 这一项中的信息就是实际向网站提交的信息。Form Data 现在只有 3 项内容。
图 5-5 查看 POST 数据
(1)source: index_nav。第一次看到这条信息肯定不了解它的含义,看上去并没有实际的意义,可以怀疑这就是一个固定提交的表单项。为了验证它,可以退出重新登录看一下,是不是还是提交了这条数据?经过验证,的确是每次登录时,系统都会提交这条数据。
(2)form_email: 984595060@qq.com 和 form_password: 963852741。这两行数据,很明显就是登录用户名和密码。至此我们已经明白登录豆瓣网站所需要的请求方法及需要提交的登录信息。
这里要说明一点,刚开始登录豆瓣这个网站的时候,是不需要验证码的,但是假设多次输错密码或者短时间内频繁登录,网站就会要求提供验证码。本小节先不用处理验证码,下一节会介绍验证码的问题。
现在已经知道了如何使用 Requests 登录豆瓣网站,也就是使用 POST 方法 - POST 前面分析的那几条数据到登录请求网址。现在还有一个非常重要的问题要解决 - 如何保持登录状态?读者应该想到了上节讲过的 Cookies 保持登录的机制,为了方便使用这个机制,Reqeusts 专门设计了一些方法,让用户可以方便地实现保持登录等状态。
5.2.2 Requests 会话对象
下面介绍 Requests 保持登录的方法 - Requests 会话对象。
Requests 会话对象能够跨请求保持某些参数如 Cookies,即同一个 Session 实例发出的所有请求都保持同一个 Cookies,而 Requests 模块每次会自动处理 Cookies,这样就可以很方便地处理登录时的保存 Cookies 问题。因此,如果想要在爬虫代码中保持登录状态,可以使用 Requests 会话对象。如果使用会话对象发起请求,底层的 TCP 连接将会被重用,也能带来显著的性能提升。
Requests 会话对象具有主要 Requests API 的所有方法,下面用例子来讲解 Requests 会话对象的使用技巧。
首先编写如下代码初始化一个会话对象。
>>>s = requests.Session()
这样就得到了一个会话对象 s,可以使用 GET 方法来获取一个网址。访问下面这个网址会设置会话对象的 Cookies 为 123456789。
>>>s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
通过访问这个网址,我们已经设置会话对象的 Cookies 为 sessioncookie=123456789,可以通过 print(s.cookies)来验证这一点。
然后再请求 http://httpbin.org/cookies,这个网址可以返回发出的请求所携带的 Cookies。
>>>r = s.get("http://httpbin.org/cookies")
可以查看返回的内容。
>>>print(r.text) '{"cookies": {"sessioncookie": "123456789"}}'
可以看到 Session 会话对象在两次请求之间保持了第一次访问所设置的 Cookies。
Session 会话对象也可用来为请求方法提供缺省数据。这是通过为会话对象的属性提供数据来实现的:
>>>s = requests.Session() #初始化会话对象 >>>s.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) \ AppleWebKit/537.36 (KHTML, like Gecko) \ Chrome/46.0.2490.80 Safari/537.36'}
这样就为会话对象添加了默认的 headers,也可以更新这个 headers。
>>>s.headers.update({'x-test': 'true'})
会话还可以用作前后文管理器。
如下代码就能确保 with 区块退出后会话能被关闭,即使发生了异常也一样。
>>>with requests.Session() as s: s.get('https://www.douban.com/')
上面介绍了 Requests 会话对象的基本使用方法,下面使用 Requests 会话对象登录并爬取豆瓣网站。
5.2.3 编写 Requests 登录豆瓣网站的代码
在不需要填写验证码的情况下,登录相对简单。在编写代码之前,再次梳理一下登录的流程。
第一步,构造需要 POST 的表单。
第二步,登录豆瓣网站,并爬取首页内容。
下面按照这个步骤编写代码。首先导入 Requests 和 Lxml 并定义 headers 和登录 URL。
>>>import requests >>>from lxml import etree >>>headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) \ AppleWebKit/537.36 (KHTML, like Gecko) \ Chrome/46.0.2490.80 Safari/537.36'} >>>url = 'https://www.douban.com/accounts/login'
根据前面的分析,构造一个 POST 表单。
>>>data = {'source':'index_nav', 'form_email':'984595060@qq.com', 'form_password':'963852741'}
这里按照我们前面的分析,把登录网站需要 POST 的信息构造为一个 dict。下面就可以初始化一个会话,并使用 POST 方法登录豆瓣网站了。
>>>s = requests.session() >>>r = s.post(url, data=data)
由此可见,使用 Requests 向网站提交数据非常简单,只需要把数据以字典的形式准备好,然后在会话中使用 data 参数提交即可。
为了验证是否已经成功登录,可以查看返回的内容中是否包含个人昵称。
>>>print('日月光华' in r.text) True
很明显,我们已经登录了个人主页。
既然已经成功登录,就可以使用这个会话继续爬取豆瓣网站的深层页面,如豆瓣为用户推送的个性化动态信息等。在爬取的过程中,Requests 会话对象会自动处理 Cookies 并为用户保持登录状态。
这一节分析了登录豆瓣网站的过程,并在代码中实现了登录豆瓣网站,读者应该从这个过程中学会分析、登录网站的方法。以后遇到一个其他的网站,也可以按照本节所示的方法分析所需提交的数据,然后在代码中登录。本节内容相对简单,并没有牵扯到填写验证码的问题,下一节将考虑如果需要填写验证码,如何实现 Requests 登录。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论