6.3 强大的Requests-HTML模块

Requests-HTML模块是requests模块的亲兄弟,是同一个开发者所开发的。Requests-HTML模块不仅包含了requests模块中的所有功能,还增加了对JavaScript的支持、数据提取以及模拟真实浏览器等功能。

6.3.1 使用Requests-HTML实现网络请求

1.GET请求

【例6.3】 发送GET请求。(实例位置:资源包\Code\06\03)

在使用Requests-HTML模块实现网络请求时,需要先通过pip install requests-html命令进行模块的安装工作,然后导入Requests-HTML模块中的HTMLSession类,接着需要创建HTML会话对象,通过会话实例进行网络请求的发送,示例代码如下:

程序运行结果如下:

     <HTML url='http://news.youth.cn/'>
2.POST请求

【例6.4】 发送POST请求。(实例位置:资源包\Code\06\04)

在实现网络请求时,POST请求也是一种比较常见的请求方式,使用Requests-HTML实现POST请求与requests的实现方法类似,都需要单独设置表单参数data,不过,也是需要通过会话实例进行网络请求的发送,示例代码如下:

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

图6.2 例6.4程序运行结果

从图6.2所示的运行结果中不仅可以看到form所对应的表单内容,还可以看到User-Agent所对应的值并不是像requests发送网络请求时所返回的默认值(python-requests/2.22.0),而是一个真实的浏览器请求头信息,这与requests模块所发送的网络请求有着细微的改进。

3.修改请求头信息

说到请求头信息,Requests-HTML是可以通过指定headers参数来对默认的浏览器请求头信息进行修改的,修改请求头信息的关键代码如下:

返回的浏览器头部信息如下:

4.生成随机请求头信息

【例6.5】 生成随机请求头信息。(实例位置:资源包\Code\06\05)

Requests-HTML模块中添加了UserAgent类,使用该类既可以实现随机生成请求头信息。示例代码如下:

返回随机生成的请求头信息如下:

     "User-Agent": "Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20130405 Firefox/22.0"

6.3.2 数据的提取

以往使用requests模块实现爬虫程序时,还需要为其配置一个解析HTML代码的搭档。Requests-HTML模块对此进行了一个比较大的升级,不仅支持CSS选择器还支持XPath的节点提取方式。

1.CSS选择器

CSS选择器中需要使用HTML的find()方法,该方法中包含5个参数,其语法格式与参数含义如下:

     find(selector:str="*",containing:_Containing=None,clean:bool=False,first:bool=False,_encoding:str=None)

 selector:使用CSS选择器定位网页元素。

 containing:通过指定文本获取网页元素。

 clean:是否清除HTML中的<script>和<style>标签,默认值为False表示不清除。

 first:是否只返回网页中第一个元素,默认值为False表示全部返回。

 _encoding:表示编码格式。

2.xpath选择器

xpath选择器同样需要使用HTML进行调用,该方法中有4个参数,其语法格式与参数含义如下:

     xpath(selector:str,clean:bool=False,first:bool=False,_encoding:str=None)

 selector:使用xpath选择器定位网页元素。

 clean:是否清除HTML中的<script>和<style>标签,默认值为False表示不清除。

 first:是否只返回网页中第一个元素,默认值为False表示全部返回。

 _encoding:表示编码格式。

3.爬取即时新闻

【例6.6】 爬取即时新闻。(实例位置:资源包\Code\06\06)

学习了Requests-HTML模块中两种提取数据的函数后,以爬取“中国青年网”即时新闻为例,数据提取的具体步骤如下。

(1)在浏览器中打开(http://news.youth.cn/jsxw/index.htm)网页地址,然后按F12键在“开发者工具”中单击Elements选项,确认“即时新闻”列表内新闻信息所在的HTML标签的位置,如图6.3所示。

图6.3 获取新闻信息的标签位置

(2)在图6.1中可以看出新闻标题在li标签中的a标签内,而a标签中的href属性值为当前新闻详情页的部分url地址,li标签中font标签内是当前新闻所发布的时间,将鼠标移至href属性所对应的url地址时,会自动显示完整的详情页地址,如图6.4所示。

图6.4 获取完整的新闻详情页地址

(3)定位以上“新闻标题”“新闻详情url地址”“新闻发布时间”信息位置后,首先创建HTML会话与获取随机请求对象,然后对“即时新闻”首页发送网络请求,代码如下:

(4)网络请求发送完成以后,需要通过请求状态码判断请求是否为200,如果是200则表示请求成功,然后根据数据定位的标签分别获取“新闻标题”“新闻详情url地址”以及新闻的发布时间,代码如下:

程序运行结果如下:

4.find()方法中containing参数

如果需要获取li标签中指定的新闻内容时,可以使用find()方法中的containing参数,以获取关于“新冠疫情”相关新闻内容为例,示例代码如下:

程序运行结果如下:

5.search()方法与search_all()方法

除了使用find()与xpath()这两种方法来提取数据以外,还可以使用search()获取search_all()方法,通过关键字提取相应的数据信息,其中search()方法表示查找符合条件的第一个元素,而search_all()方法则表示符合条件的所有元素。

使用search()方法获取关于“新冠疫情”新闻信息为例,示例代码如下:

使用search_all()方法获取关于“新冠疫情”新闻信息为例,示例代码如下:

说明

在使用search()与search_all()方法获取数据时,方法中的一个{}表示获取一个内容。

6.3.3 获取动态加载的数据

【例6.7】 获取动态加载的数据。(实例位置:资源包\Code\06\07)

在爬取网页数据时,经常会遇到直接对网页地址发送请求,但返回的HTML代码中并没有所需要的数据的情况,这多数都是因为网页数据使用了Ajax请求并由JavaScript渲染到网页中。例如爬取(https://movie.douban.com/tag/#/?sort=U&range=0,10&tags=%E7%94%B5%E5%BD%B1,2020)豆瓣2020年电影数据时,就需要通过浏览器开发者工具获取Ajax请求后的电影信息,如图6.5所示。

为了避免图6.5所示的麻烦操作,Requests-HTML提供了render()方法,第一次调用该方法将会自动下载Chromium浏览器,然后通过该浏览器直接加载JavaScript渲染后的信息,使用render()方法爬取豆瓣2020年电影数据的具体步骤如下:

(1)创建HTML会话与随机请求头对象,然后发送网络请求,在请求成功的情况下调用render()方法获取网页中JavaScript渲染后的信息。示例代码如下:

图6.5 获取Ajax请求后的电影信息

(2)运行步骤(1)中代码,由于第一次调用render()方法,所以会自动下载Chromium浏览器,下载完成后控制台将显示如图6.6所示的提示信息。

图6.6 Chromium浏览器下载完成后的提示信息

(3)打开浏览器“开发者工具”,在Elements的功能选项中确认电影信息所在HTML标签的位置,如图6.7所示。

图6.7 获取电影信息的标签位置

(4)编写获取电影信息的代码,首先是当前页面中所有电影信息的a标签,然后在a标签中逐个获取电影名称、电影评分、详情页url地址以及电影图片地址。示例代码如下:

程序运行的部分结果如下: