Python 爬虫网页内容提取工具xpath(二)

Python爬虫 2018-12-08 22:19:54 阅读(6147) 评论(0)

前面几节,我们讲述了操作html文档的相关知识,接下来我们就以猿人学首页的内容提取为例,用实例展示lxml和xpath提取网页数据的魅力。

目标 提取首页文章的信息,包括标题、作者、发布时间、阅读数、评论数、网址

PS:还没了解 lxml和xpath的同学,先看下前面几篇打底文章。
Python 爬虫网页解析工具lxml.html(一)
Python 爬虫网页解析工具lxml.html(二)
Python 爬虫网页内容提取工具xpath(一)

先研究一下猿人学首页的结构

猿人学首页的截图如下:

猿人学首页截图

结构简洁清晰,对爬虫很友好嘛,哈哈哈~~
左右结构,左侧是主体部分,置顶了几篇文章,下面的红色框里面的就是一篇篇文章的列表,也就是我们要提取的部分。
用Chrome打开网页,按F12调出网页分析工具,可以看到文章列表在一个<ul>下面,一个<li>就是一篇文章的数据:

猿人学首页文章列表html

获取网页并生成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}

知识点

  1. 如果刚一开始对xpath不太熟悉,可以借助Chrome的F12查看元素来获得XPath,右键点击想要获取的节点,选择菜单即可:

Chrome获取XPath

猿人学banner宣传图

我的公众号:猿人学 Python 上会分享更多心得体会,敬请关注。

***版权申明:若没有特殊说明,文章皆是猿人学 yuanrenxue.con 原创,没有猿人学授权,请勿以任何形式转载。***

说点什么吧...