很多朋友都听说过Python的大名,而Python也拥有众多的爬虫框架,其中最简单的莫过于requests-html了。它和著名的网络请求库requests是同一个作者,着重于XML数据提取,可以说是最简单的爬虫框架了。
安装requests-html
安装这个类库非常简单,直接通过pip就可以安装了。
pip install requests-html
开始使用
requests-html用起来也十分简单,下面是一个简单例子。照例说明一下,第一段引入了HTMLSession用于创建连接,获取网页数据。第二段创建连接,获取了我的简书用户页面。第三段用xpath语法获取了网页上的用户名,最后打印出来。
from requests_html import HTMLSessionsession = HTMLSession()response = session.get( 'https://www.jianshu.com/u/7753478e1554')username = response.html.xpath( '//a[@class="name"]/text()', first=True)print(username)
看起来是不是很简单?没错,确实很简单,接下来还有一些更加有趣的功能。
分析网页
编写爬虫之前还要做一件事情,就是分析网页的结构。这个工作其实也很简单,打开你要访问的网页,按F12打开开发人员工具,可以看到最左边有这么一个按钮。点击这个按钮,然后点击网页上你想要查看的网页元素,然后你就可以发现这个元素对应的相关源代码已经为你定位完毕了。
通过这个功能,我们就可以轻松的分析网页,然后通过它的结构来编写爬虫了。
提取数据
上面的response.html即是网页的根节点HTML节点,在节点对象上可以调用一些方法来检索数据。最常用的方法是find方法,它通过CSS选择器来定位数据。对于上面的例子,可以用find方法改写第三段。
因为所有查找方法返回的结果都是列表,所以如果你确定只需要查找一个,就将first参数设为真来只返回第一个结果。find方法返回的仍然是一个节点,如果只需要节点的内容,调用其text属性即可。
用户名对应的HTML结构如图所示。
代码如下。
username = response.html.find('a.name', first=True).text
除了find方法之外,还可以使用xpath方法用xpath语法来查找节点,正如第一个例子那样。我个人比较喜欢xpath语法,CSS选择器虽然更加流行一些,但是写出来的效果有点怪,不如xpath工整。
同样是这个页面,看看如何获取我的简书的个人简介。网页代码如图所示。
代码如下。
description = response.html.xpath( '//div[@class="description"]/div[@class="js-intro"]/text()', first=True)
CSS选择器和XPATH语法都不是本篇的主要内容,如果你这方面不太熟悉,最好去看一下相关的教程。当然如果大家有什么疑问的话,也可以提出来。假如大家想看的话,我也可以专门写一篇文章介绍一下这些语法知识。
渲染网页
有些网页利用了前后端分离技术开发的,需要浏览器渲染才能完整显示。如果用爬虫去看的话,只能显示一部分内容。这时候就需要浏览器渲染页面,才能获取完整的页面。用requests-html的话,这个过程非常简单。
首先先来看看一个需要渲染网页的例子。下面的代码访问了我的简书用户页面,然后尝试获取我的所有文章。但是如果你运行这个例子的话,就会发现只能获取前几项。因为简书的页面正是一个典型的需要浏览器渲染的页面,爬虫获取到的网页是不完整的。
from requests_html import HTMLSessionsession = HTMLSession()headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.119 Safari/537.36'}url = 'https://www.jianshu.com/u/7753478e1554'r = session.get(url, headers=headers)for a in r.html.xpath('//ul[@class="note-list"]/li/div[@class="content"]/a[@class="title"]'): title = a.text link = f'https://www.jianshu.com{a.attrs["href"]}' print(f'《{title}》,{link}')
那么如何渲染网页来获取完整的结果呢?其实非常简单,在查询HTML节点之前,调用render函数即可。
原理也非常简单,第一次调用render的时候,requests-html会在本地下载一个chromium浏览器,用它来渲染网页。如此一来,我们就可以获取到渲染之后的页面了。
但是对于简书这个例子来说还是有些问题,因为如果你在浏览器里打开这个网页的话,会发现一些文章在浏览器下滑页面的时候才开始渲染。不过聪慧的作者早就考虑到这种情况了,render函数支持下滑的参数,设定之后,就会模拟浏览器下滑操作,从而解决了这个问题。
r.html.render(scrolldown=50, sleep=0.2)
节点对象
不论上面的r.html还是find/xpath函数返回的结果,它们都是节点对象。除了上面介绍的几个提取数据的方法以外,节点对象还有以下一些属性,在我们提取数据的时候也有很大作用。
相较于专业的爬虫框架scrapy,或者仅用于解析XML的解析库BeautifulSoup。requests-html可以是说恰到好处,它没有前者那么难学,也不像后者还需要搭配HTTP请求库才能使用。如果你手头需要临时抓取几个网页,那么requests-html就是你最好的选择。