python爬虫基础之xpath使用教程

介绍

XPath是一种XML路径语言,被用于在XML文档中通过元素和属性进行导航

安装

pip install lxml

使用

html示例内容,下面的所有练习全都来自与此段示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <style>
        .color1 {
            color: red;
            text-decoration: none;
        }
        .color2 {
            color: blue;
        }
        #color3 {
            color: pink;
            text-decoration: none;
        }
    </style>
</head>
<body>
<p>this is a text</p>
<span class="color1">
    <p>this is a span</p>
</span>
<div>
    <p>this is a list</p>
    <ul>
        <li><a href="#" class="color1">北京</a></li>
        <li><a href="#" id="color3">上海</a></li>
        <li><a href="#" class="color2">广州</a></li>
        <li><a href="https://www.dogfei.cn">西二旗</a></li>
    </ul>
</div>
</body>
</html>

读取html内容

from lxml import etree

with open('test.html', 'r', encoding='utf-8') as fr:
    html = fr.read()
    et = etree.HTML(html)

下面就接着这个代码段往下写。

所有节点、父节点、子孙节点

所有节点是通过指定'//*'来获取,例如

et.xpath('//*')

返回如下:

[<Element html at 0x173aa409e88>, <Element head at 0x173aa540788>, <Element meta at 0x173aa5407c8>, <Element title at 0x173aa540848>, <Element style at 0x173aa540a48>, <Element body at 0x173aa540a88>, <Element p at 0x173aa540b08>, <Element div at 0x173aa540b48>, <Element p at 0x173aa540b88>, <Element ul at 0x173aa540948>, <Element li at 0x173aa540bc8>, <Element a at 0x173aa540c08>, <Element li at 0x173aa540c48>, <Element a at 0x173aa540c88>, <Element li at 0x173aa540cc8>, <Element a at 0x173aa540d08>, <Element li at 0x173aa540d48>, <Element a at 0x173aa540d88>]

子孙结点是通过'//'来获取

# 获取所有的li节点
et.xpath('//li')

父节点是通过'..'来获取,有点像linux的..上级目录

et.xpath('//p/../@class')

结果为

['color1']

获取文本text()

res0 = et.xpath('//body/p/text()')

返回结果

['this is a text']

获取指定标签下的内容

res1 = et.xpath('//li[1]/a/text()')
print(res1)

返回结果

['北京']

指定具体的标签

res2 = et.xpath('//div/p/')
print(res2)

返回内容

[<Element p at 0x23b49990888>]

指定类选择器

res3 = et.xpath('//li/a[@class="color2"]/text()')
print(res3)

返回结果

['广州']

指定id选择器

res4 = et.xpath('//li/a[@id="color3"]/text()')
print(res4)

返回结果

['上海']

模糊匹配

res5 = et.xpath('//li/a[contains(@href, "http")]/text()')
print(res5)

返回结果

['西二旗']

指定某个属性的具体值

res6 = et.xpath('//li/a[@href="https://www.dogfei.cn"]/text()')
print(res6)

返回结果

['西二旗']

获取指定位置的内容

res7 = et.xpath('//li[last()]/a/text()')
print(res7)

返回结果

['西二旗']

也可以用[last() - 1]

还可以使用position()

res8 = et.xpath('//li[position() < 3]/a/text()')
print(res8)

返回结果

['北京', '上海']

通过使用position()可以获取到一组数据

通配符

res9 = et.xpath('//li/*/text()') # *也可以省略
print(res9)

返回结果

['北京', '上海', '广州', '西二旗']

指定所有属性

res10 = et.xpath('//li//a[@*]/text()')
print(res10)

返回结果

['北京', '上海', '广州', '西二旗']

使用./再次查找

res11 = et.xpath('//li')
for i in res11:
    r = i.xpath('./a/text()')[0]
    print(r)

返回结果

北京
上海
广州
西二旗

实战案例

此案例简单来爬取豆瓣电影的top250,只拿第一页的数据,打印出排名和电影名,重点是来掌握xpath的用法

豆瓣电影top250的访问地址为:https://movie.douban.com/top250

查看页面源代码或者浏览器f12查看页面元素定位到标签位置,打开其中一段分析来看:

<ol class="grid_view">
                    <li>
                        <div class="item">
                            <div class="pic">
                                <em class="">1</em>
                                <a href="https://movie.douban.com/subject/1292052/">
                                    <img width="100" alt="肖申克的救赎"
                                         src="https://img2.doubanio.com/view/photo/s_ratio_poster/public/p480747492.webp"
                                         class="">
                                </a>
                            </div>
                            <div class="info">
                                <div class="hd">
                                    <a href="https://movie.douban.com/subject/1292052/" class="">
                                        <span class="title">肖申克的救赎</span>
                                        <span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span>
                                        <span class="other">&nbsp;/&nbsp;月黑高飞(港)  /  刺激1995(台)</span>
                                    </a>


                                    <span class="playable">[可播放]</span>
                                </div>
                                <div class="bd">
                                    <p class="">
                                        导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /...<br>
                                        1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情
                                    </p>


                                    <div class="star">
                                        <span class="rating5-t"></span>
                                        <span class="rating_num" property="v:average">9.7</span>
                                        <span property="v:best" content="10.0"></span>
                                        <span>2468198人评价</span>
                                    </div>

                                    <p class="quote">
                                        <span class="inq">希望让人*。</span>
                                    </p>
                                </div>
                            </div>
                        </div>
                    </li>
.....
.....
.....
.....
</ol>
  1. 可以看到电影都在ol这个有序标签内,ol标签中的类属性值grid_view这个是惟一的,直接用xpath,通过类选择器来拿到这段html,然后再进一步处理。

  2. 由于这里是一个列表,所以得需要进行遍历,既然是遍历,那就应该拿到所有的li标签下的内容,然后遍历

  3. 每遍历一次列表,就会拿到每一个电影的信息,然后可以找到排名信息是在em标签下,电影名称是在第一个span标签下

from lxml import etree
import requests


def get_resource_html(url):
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"
    }
    res = requests.get(url, headers=headers).text
    res.encode('utf-8')
    return res


def parse_html(html):
    et = etree.HTML(html)
    movie_list = et.xpath('//ol[@class="grid_view"]/li')
    for movie in movie_list:
        movie_ranking = movie.xpath('.//div[@class="pic"]/em/text()')[0]
        movie_title = movie.xpath('.//div[@class="info"]//span[1]/text()')[0]
        with open('movie.csv', 'a+', encoding='utf-8') as fw:
            fw.write(f"{movie_ranking},{movie_title}\n")
    return

def main():
    url = "https://movie.douban.com/top250"
    html = get_resource_html(url)
    parse_html(html)

if __name__ == '__main__':
    main()

执行结果

python爬虫基础之xpath使用教程


欢迎各位朋友关注我的公众号,来一起学习进步哦
python爬虫基础之xpath使用教程

上一篇:爬虫入门教程⑩— 用漂亮的图表展示爬取到的数据


下一篇:Linux编译安装libmodbus库