前面几节,我们讲述了操作html文档的相关知识,接下来我们就以猿人学首页的内容提取为例,用实例展示lxml和xpath提取网页数据的魅力。
目标 提取首页文章的信息,包括标题、作者、发布时间、阅读数、评论数、网址
PS:还没了解 lxml和xpath的同学,先看下前面几篇打底文章。
Python 爬虫网页解析工具lxml.html(一)
Python 爬虫网页解析工具lxml.html(二)
Python 爬虫网页内容提取工具xpath(一)
先研究一下猿人学首页的结构
猿人学首页的截图如下:
结构简洁清晰,对爬虫很友好嘛,哈哈哈~~
左右结构,左侧是主体部分,置顶了几篇文章,下面的红色框里面的就是一篇篇文章的列表,也就是我们要提取的部分。
用Chrome打开网页,按F12调出网页分析工具,可以看到文章列表在一个<ul>
下面,一个<li>
就是一篇文章的数据:
获取网页并生成lxml的文档节点
import requests
from lxml.html
headers = {'User-Agent': 'Firefox'}
resp = requests.get('https://www.yuanrenxue.cn/', headers=headers)
html = resp.content.decode('utf8')
doc = lxml.html.fromstring(html)
惊天!猿人学竟然封锁了requests的user-agent!!我不得不自定义header来绕过它的封锁,哈哈哈~~~
这里,我们自己解码resp.content,而不是直接用的resp.text。对于utf8编码的网页,resp.text也是可以的,但是为什么要自己解码呢? 具体原因可以看看教程的另一篇文章:大规模异步新闻爬虫:实现一个更好的网络请求函数 关于cchardet模块的说明。
提取数据
首先,获取文章列表的所有<li>
,根据前面我们研究得到的网页结构,不难写出对应的xpath:
In [241]: xp = '//ul[@id="postlist"]/li'
In [242]: lis = doc.xpath('//ul[@id="postlist"]/li')
In [243]: lis
Out[243]:
[<Element li at 0x7fc409fb68b8>,
<Element li at 0x7fc409fb6c78>,
<Element li at 0x7fc409fb6908>,
<Element li at 0x7fc40a0ebef8>,
<Element li at 0x7fc409fb7098>,
<Element li at 0x7fc40a260138>,
<Element li at 0x7fc40a2602c8>,
<Element li at 0x7fc40a260188>,
<Element li at 0x7fc40a2a5a98>,
<Element li at 0x7fc40a2a59f8>]
In [244]: len(lis)
Out[244]: 10
然后,解析<li>
,提取单篇文章的要素,同样在浏览器查看一下<li>
的结构:
结构清晰明朗,提取起来毫无压力,猿人学真是爬虫友好的好网站啊,哈哈哈~
下面我就看着网页结构来写提取要素的函数:
def parse(li):
item = {}
# class="thumb"的div有两个<a>,第一个是类别链接,第二个是文章链接
thumb = li.xpath('./div[@class="thumb"]/a')
item['cat'] = thumb[0].text
item['link'] = thumb[1].get('href')
# 获取title
el_title = li.xpath('.//h2[@class="info-tit"]/a')[0]
item['title'] = el_title.text
el_info = li.xpath('.//div[@class="info-item"]/span')
for span in el_info:
attr = span.get('class')
if attr == 'author':
item['author'] = span.text_content()
elif attr == 'time':
item['time'] = span.text_content()
elif attr == 'view':
digit = re.findall(r'\d+', span.text_content())[0]
item['view_count'] = int(digit)
elif attr == 'cmt':
digit = re.findall(r'\d+', span.text_content())[0]
item['cmt_count'] = int(digit)
return item
以上,我们就完整的提取出了猿人学首页显示的最新10篇文章的数据。上面代码片段的完整代码可以到本教程的github查看、下载。
运行一下完整代码,并打印出提出的第一篇文章的详细信息,可以看到输出结果:
lis: 10
articles: 10
{'author': '王平',
'cat': 'python爬虫教程',
'cmt_count': 0,
'link': 'https://www.yuanrenxue.cn/crawler/crawler-tricks-2.html',
'time': '\ue60419小时前',
'title': '网络爬虫小偏方:修改referer绕开登录和访问频率限制',
'view_count': 505}
知识点
- 如果刚一开始对xpath不太熟悉,可以借助Chrome的F12查看元素来获得XPath,右键点击想要获取的节点,选择菜单即可:

我的公众号:猿人学 Python 上会分享更多心得体会,敬请关注。
***版权申明:若没有特殊说明,文章皆是猿人学 yuanrenxue.con 原创,没有猿人学授权,请勿以任何形式转载。***
说点什么吧...