Python网络爬虫从入门到精通
上QQ阅读APP看书,第一时间看更新

5.2 复杂的网络请求

在使用requests模块实现网络请求时,不只有简单的GET与POST。还有复杂的请求头、Cookies以及网络超时等。不过,requests模块将这一系列复杂的请求方式进行了简化,只要在发送请求时设置对应的参数即可实现复杂的网络请求。

5.2.1 添加请求头headers

【例5.5】 添加请求头。(实例位置:资源包\Code\05\05)

有时在请求一个网页内容时,发现无论通过GET或者POST以及其他请求方式,都会出现403错误。这种现象多数为服务器拒绝了访问,因为这些网页为了防止恶意采集信息,所以使用了反爬虫设置。此时可以通过模拟浏览器的头部信息来进行访问,这样就能解决以上反爬设置的问题。下面介绍requests模块添加请求头的方式,代码如下:

程序运行结果如下:

     200

5.2.2 验证Cookies

【例5.6】 通过验证Cookies模拟豆瓣登录。(实例位置:资源包\Code\05\06)

在爬取某些数据时,需要进行网页的登录,才可以进行数据的抓取工作。Cookies登录就像很多网页中的自动登录功能一样,可以让用户在第二次登录时,在不需要验证账号和密码的情况下进行登录。在使用requests模块实现Cookies登录时,首先需要在浏览器的开发者工具页面中找到可以实现登录的Cookies信息,然后将Cookies信息处理并添加至RequestsCookieJar的对象中,最后将RequestsCookieJar对象作为网络请求的Cookies参数,发送网络请求即可。以获取豆瓣网页登录后的用户名为例,具体步骤如下。

(1)在谷歌浏览器中打开豆瓣网页地址(https://www.douban.com/),然后按F12键打开网络监视器,选择“密码登录”输入“手机号/邮箱”与“密码”,然后单击“登录豆瓣”,网络监视器将显示如图5.9所示的数据变化。

图5.9 网络监视器的数据变化

(2)在Headers选项中选中Request Headers选项,获取登录后的Cookie信息,如图5.10所示。

图5.10 找到登录后网页中的Cookie信息

(3)导入相应的模块,将“找到登录后网页中的Cookie信息”以字符串形式保存,然后创建RequestsCookieJar()对象并对Cookie信息进行处理,最后将处理后的RequestsCookieJar()对象作为网络请求参数,实现网页的登录请求。代码如下:

程序运行结果如下:

     阿四sir的账号

5.2.3 会话请求

在实现获取某个登录后页面的信息时,可以使用设置Cookies的方式先实现模拟登录,然后再获取登录后页面的信息内容。这样虽然可以成功地获取页面中的信息,但是比较烦琐。

【例5.7】 实现会话请求。(实例位置:资源包\Code\05\07)

requests模块中提供了Session对象,通过该对象可以实现在同一会话内发送多次网络请求,这相当于在浏览器中打开了一个新的选项卡。此时再获取登录后页面中的数据时,可以发送两次请求,第一次发送登录请求,第二次请求就可以在不设置Cookies的情况下获取登录后的页面数据。示例代码如下:

程序运行结果如图5.11所示。

图5.11 登录后的请求结果

5.2.4 验证请求

在访问页面时,可能会出现如图5.12所示的验证页面,然后输入用户名与密码后才可以访问如图5.13所示的页面数据。

图5.12 验证页面

图5.13 验证后的页面

【例5.8】 验证请求。(实例位置:资源包\Code\05\08)

requests模块自带了验证功能,只需要在请求方法中填写auth参数,该参数的值是一个带有验证参数(用户名与密码)的HTTPBasicAuth对象。示例代码如下:

程序运行结果如图5.14所示。

图5.14 验证后页面中的HTML代码

5.2.5 网络超时与异常

【例5.9】 演示网络超时与异常。(实例位置:资源包\Code\05\09)

在访问一个网页时,如果该网页长时间未响应,那么系统就会判断该网页超时,从而无法打开网页。下面通过代码来模拟一个网络超时的现象,代码如下:

程序运行结果如图5.15所示。

图5.15 超时异常信息

说明

在上面的代码中,模拟进行了50次循环请求,并且设置了超时的时间为0.1秒,在0.1秒内服务器未做出响应将视为超时,所以将超时信息打印在控制台中。根据以上的模拟测试结果,可以确认在不同的情况下设置不同的timeout值。

【例5.10】 识别网络异常的分类。(实例位置:资源包\Code\05\10)

说起网络异常信息,requests模块同样提供了3种常见的网络异常类,代码如下:

5.2.6 上传文件

【例5.11】 上传图片文件。(实例位置:资源包\Code\05\11)

使用requests模块实现向服务器上传文件也是很简单的,只需要指定post()函数中的files参数即可。files参数可以指定一个BufferedReader对象,该对象可以使用内置的open()函数返回。使用requests模块实现上传文件的代码如下:

程序运行结果如图5.16所示。

图5.16 例5.11程序运行结果

说明

从图5.16所示的程序运行结果中可以看出,提交的图片文件(二进制数据)被指定在files中,从框内file对应的数据中可以发现,post()函数将上传的文件转换成了base64的编码形式。

注意

程序运行结果中框内尾部的…为省略部分。