前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Python爬虫之xpath语法及案例使用

Python爬虫之xpath语法及案例使用

作者头像
钢铁知识库
发布于 2022-08-20 01:10:00
发布于 2022-08-20 01:10:00
1.1K00
代码可运行
举报
文章被收录于专栏:python爬虫教程python爬虫教程
运行总次数:0
代码可运行

Python爬虫之xpath语法及案例使用

---- 钢铁侠的知识库 2022.08.15

我们在写Python爬虫时,经常需要对网页提取信息,如果用传统正则表达去写会增加很多工作量,此时需要一种对数据解析的方法,也就是本章要介绍的Xpath表达式。

Xpath是什么

XPath,全称 XML Path Language,即 XML 路径语言,它是一门在 XML 文档中查找信息的语言。最初是用来搜寻 XML 文档的,但同样适用于 HTML 文档的搜索。所以在做爬虫时完全可以使用 XPath 做相应的信息抽取。

XPath 的选择功能十分强大,它提供了非常简洁明了的路径选择表达式。另外,它还提供超过 100 个内置函数,用于字符串、数值、时间的匹配以及节点、序列的处理等,几乎所有想要定位的节点都可以用 XPath 来选取。

下面介绍实战中常用的几个知识点,详细也可以看W3C介绍:https://www.w3school.com.cn/xpath/index.asp

Xpath语法介绍

路径常用规则

表达式

描述

实例

nodename

选取此节点的所有子节点

xpath('//div')

选取了div节点的所有子节点

/

从根节点选取

xpath('/div')

从根节点上选取div节点

//

选取所有当前节点,不考虑位置

xpath('//div')

选取所有的div节点

.

选取当前节点

xpath('./div')

选取当前节点下的div节点

..

选取当前节点的父节点

xpath('..')

回到上一个节点

@

选取属性

xpath('//@calss')

选取所有的class属性

谓语规则

谓语被嵌在方括号内,用来查找某个特定的节点或包含某个制定的值的节点

表达式

结果

xpath('/body/div[1]')

选取body下的第一个div节点

xpath('/body/div[last()]')

选取body下最后一个div节点

xpath('/body/div[last()-1]')

选取body下倒数第二个div节点

xpath('/body/div[positon()❤️]')

选取body下前两个div节点

xpath('/body/div[@class]')

选取body下带有class属性的div节点

xpath('/body/div[@class="main"]')

选取body下class属性为main的div节点

xpath('/body/div[price>35.00]')

选取body下price元素值大于35的div节点

通配符

通配符来选取未知的XML元素

表达式

结果

xpath('/div/*')

选取div下的所有子节点

xpath('/div[@*]')

选取所有带属性的div节点

取多个路径

使用“|”运算符可以选取多个路径

表达式

结果

xpath('//div|//table')

选取所有的div和table节点

功能函数

使用功能函数能够更好的进行模糊搜索

函数

用法

解释

starts-with

xpath('//div[starts-with(@id,"ma")]')

选取id值以ma开头的div节点

contains

xpath('//div[contains(@id,"ma")]')

选取id值包含ma的div节点

and

xpath('//div[contains(@id,"ma") and contains(@id,"in")]')

选取id值包含ma和in的div节点

text()

xpath('//div[contains(text(),"ma")]')

选取节点文本包含ma的div节点

语法熟悉

下面举一段HTML文本进行语法热身,代码如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# time: 2022/8/8 0:05
# author: gangtie
# email: 648403020@qq.com
from lxml import etree

text = '''
<div>
            <ul id='ultest'>
                 <li class="item-0"><a href="link1.html">first item</a></li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-inactive"><a href="link3.html">third item</a></li>
                 <li class="item-1"><a href="link4.html"><span>fourth item</span></a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a>
             </ul>
         </div>
'''
# 调用HTML类进行初始化,这样就成功构造了一个XPath解析对象。
# 利用etree.HTML解析字符串
page = etree.HTML(text)   
print(type(page))

可以看到打印结果已经变成XML元素:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<class 'lxml.etree._Element'>
字符串转换HTML

字符串利用etree.HTML解析成html格式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
print(etree.tostring(page,encoding='utf-8').decode('utf-8'))

```
<html><body><div>
            <ul id="ultest">
                 <li class="item-0"><a href="link1.html">first item</a></li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-inactive"><a href="link3.html">third item</a></li>
                 <li class="item-1"><a href="link4.html"><span>fourth item</span></a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a>
             </li></ul>
         </div>
</body></html>

Process finished with exit code 0
```

经过处理可以看到缺失的</li>也自动补全了,还自动添加html、body节点。

查找绝对路径

通过绝对路径获取a标签的所有内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
a = page.xpath("/html/body/div/ul/li/a")
for i in a:
    print(i.text)

```
first item
second item
third item
None
fifth item
```
查找相对路径(常用)

查找所有li标签下的a标签内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
html = etree.HTML(text)
a = html.xpath("//a/text()")
print(a)

```
['first item', 'second item', 'third item', 'fifth item']
```
当前标签节点

. 表示选取当前标签的节点。

我们先定位 ul 元素节点得到一个列表,打印当前节点列表得到第一个 ul, 接着打印 ul 节点的子节点 li,text()输出。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
page = etree.HTML(text)
ul = page.xpath("//ul")
print(ul)
print(ul[0].xpath("."))
print(ul[0].xpath("./li"))
print(ul[0].xpath("./li/a/text()"))

```
[<Element ul at 0x234d16186c0>]
[<Element ul at 0x234d16186c0>]
[<Element li at 0x234d1618ac0>, <Element li at 0x234d1618b00>, <Element li at 0x234d1618b40>, <Element li at 0x234d1618b80>, <Element li at 0x234d1618bc0>]
['first item', 'second item', 'third item', 'fifth item']
```
父节点

.. 表示选取当前标签的父节点。

可以看到得到ul的上一级div

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
page = etree.HTML(text)
ul = page.xpath("//ul")
print(ul[0].xpath("."))
print(ul[0].xpath(".."))

```
[<Element ul at 0x1d6d5cd8540>]
[<Element div at 0x1d6d5cd8940>]
```
属性匹配

匹配时可以用@符号进行属性过滤 查找a标签下属性href值为link2.html的内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
html = etree.HTML(text)
a = html.xpath("//a[@href='link2.html']/text()")
print(a)

```
['second item']
```
函数

last():查找最后一个li标签里的a标签的href属性

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
html = etree.HTML(text)
a = html.xpath("//li[last()]/a/text()")
print(a)

```
['fifth item']
```

contains:查找a标签中属性href包含link的节点,并文本输出

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
html = etree.HTML(text)
a = html.xpath("//a[contains(@href, 'link')]/text()")
print(a)

```
['first item', 'second item', 'third item', 'fifth item']
```

实战案例

上面说完基本用法,接下来做几个实战案例练练手。

案例一:豆瓣读书

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#  -*-coding:utf8 -*-
# 1.请求并提取需要的字段
# 2.保存需要的数据
import requests
from lxml import etree

class DoubanBook():

    def __init__(self):
        self.base_url = 'https://book.douban.com/chart?subcat=all&icn=index-topchart-popular'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/104.0.0.0 Safari/537.36'
        }

    # 请求并提取需要的字段
    def crawl(self):
        res = requests.get(self.base_url, headers=self.headers)
        lis = etree.HTML(res.text).xpath('//*[@id="content"]/div/div[1]/ul/li')
        # print(type(lis))
        books = []
        for li in lis:
            # print(etree.tostring(li,encoding='utf-8').decode('utf-8'))
            # print("==================================================")
            title = "".join(li.xpath(".//a[@class='fleft']/text()"))
            score = "".join(li.xpath(".//p[@class='clearfix w250']/span[2]/text()"))
            # list输出带有['\n                    刘瑜 / 2022-4 / 广西师范大学出版社 / 82.00元 / 精装\n                ']
            publishing = "".join(li.xpath(".//p[@class='subject-abstract color-gray']/text()")).strip()
            book = {
                'title': title,
                'score': score,
                'publishing': publishing,
            }
            books.append(book)
        self.save_data(books)

    def save_data(self, datas):
            with open('books.txt', 'w', encoding='utf-8') as f:
                f.write(str(datas))

    def run(self):
        self.crawl()

if __name__ == '__main__':
    DoubanBook().run()

案例二:彼岸图片下载

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author: 钢铁知识库
# email: 648403020@qq.com

import os
import requests
from lxml import etree

# 彼岸图片下载
class BiAn():

    def __init__(self):
        self.url = 'https://pic.netbian.com'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/104.0.0.0 Safari/537.36',
            'cookie': '__yjs_duid=1_cb922eedbda97280755010e53b2caca41659183144320; Hm_lvt_c59f2e992a863c2744e1ba985abaea6c=1649863747,1660203266; zkhanecookieclassrecord=%2C23%2C54%2C55%2C66%2C60%2C; Hm_lpvt_c59f2e992a863c2744e1ba985abaea6c=1660207771; yjs_js_security_passport=1225f36e8501b4d95592e5e7d5202f4081149e51_1630209607_js'
        }
        # 如果目录不存在会报错
        if not os.path.exists('BianPicture'):
            os.mkdir('BianPicture')

    # 请求拿到ul列表
    def crawl(self):
        res = requests.get(self.url, headers=self.headers)
        res.encoding = 'gbk'
        uls = etree.HTML(res.text).xpath('//div[@class="slist"]/ul[@class="clearfix"]/li')
        # print(etree.tostring(uls,encoding='gbk').decode('gbk'))

        # 循环拿到图片名、图片地址,拼接请求再次下载到图片
        for ul in uls:
            img_name = ul.xpath('.//a/b/text()')[0]
            img_src = ul.xpath('.//a/span/img/@src')[0]
            # print(img_name + img_src)
            img_url = self.url + img_src
            # 拼接后下载图片,转义Bytes
            img_res = requests.get(img_url, headers=self.headers).content
            img_path = "BianPicture/" + img_name + ".jpg"
            data = {
                'img_res': img_res,
                'img_path': img_path
            }
            self.save_data(data)

    # 数据保存逻辑
    def save_data(self, data):
        with open(data['img_path'], 'wb') as f:
            f.write(data['img_res'])
        # print(data)

    def run(self):
        self.crawl()

if __name__ == '__main__':
    BiAn().run()

案例三:全国城市名称爬取

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author: 钢铁知识库
# email: 648403020@qq.com
import os

import requests
from lxml import etree

class CityName():
    def __init__(self):
        self.url = 'https://www.aqistudy.cn/historydata/'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
        }
        # 判断目录是否存在
        if not os.path.exists('city_project'):
            os.mkdir('city_project')

    def crawl(self):
        res = requests.get(url=self.url, headers=self.headers).text
        uls = etree.HTML(res).xpath('//div[@class="all"]/div[2]/ul/div[2]/li')

        all_city_name = list()
        for ul in uls:
            city_name = ul.xpath('.//a/text()')[0]
            # print(type(city_name))
            all_city_name.append(city_name)
            self.save_data(all_city_name)

    def save_data(self, data):
        with open('./city_project/city.txt', 'w') as f:
            f.write(str(data))

    def run(self):
        self.crawl()

if __name__ == '__main__':
    CityName().run()

xpath使用工具

chrome生成XPath表达式

经常使用chome的朋友都应该知道这功能,在 审查 状态下(快捷键ctrl+shift+i,F12),定位到元素(快捷键ctrl+shift+c) ,在Elements选项卡中,右键元素 Copy->Copy xpath,就能得到该元素的xpath了

Xpath Helper插件

为chome装上XPath Helper就可以很轻松的检验自己的xpath是否正确了。安装插件需要特别上网,安装好插件后,在chrome右上角点插件的图标,调出插件的黑色界面,编辑好xpath表达式,表达式选中的元素被标记为黄色

---- 钢铁侠的知识库 2022.08.15

结语:

以上就是利用XPath的所有用法,从常用语法,到案例练习都走了一遍。下一章 钢铁知识库 会继续介绍另一种好用的解析框架,Beautiful Soup

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=oogrefjvrp08

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
python爬虫之lxml库xpath的基本使用
XPath的更多用法参考:http://www.w3school.com.cn/xpath/index.asp
菲宇
2022/12/21
1.2K0
python爬虫之lxml库xpath的基本使用
XPath语法和lxml模块
xpath(XML Path Language)是一门在XML和HTML文档中查找信息的语言,可用来在XML和HTML文档中对元素和属性进行遍历。
用户2200417
2022/02/18
1.2K0
Python爬虫——XPath
XPath 表达式 描述 nodename 选取此节点的所有子节点 / 从根节点选取 //xxx 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 . 选取当前节点 .. 选取当前节点的父节点 @xxx 选取属性内容 /text() 选取文本内容 starts-with(@属性名称,属性字符相同部分) 以相同字符开始 演示使用HTML内容 html = ''' <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8">
羊羽shine
2019/05/28
7190
Python爬虫技术系列-02HTML解析-xpath与lxml
参考连接: XPath教程 https://www.w3school.com.cn/xpath/index.asp lxml文档 https://lxml.de/index.html#support-the-project 爬虫专栏 https://blog.csdn.net/m0_38139250/category_12001010.html
用户2225445
2023/10/16
4040
Python爬虫技术系列-02HTML解析-xpath与lxml
正则表达式学废了?xpath来救!
XPath,全称XML Path Language,即XML路径语言,它是在XML语言中查找信息的语言。它最初是用来搜寻XML文档的,但是它同样适用于HTML文档的搜索。
我被狗咬了
2021/01/13
7970
正则表达式学废了?xpath来救!
Python爬虫(十二)_XPath与lxml类库
Python学习指南 有同学说,我正则用的不好,处理HTML文档很累,有没有其他的方法? 有!那就是XPath,我们可以用先将HTML文档转换成XML文档,然后用XPath查找HTML节点或元素。 什么是XML XML指可扩展标记语言(Extensible Markup Language) XML是一种标记语言,很类似HTML XML的设计宗旨是传输数据,而非显示数据。 XML的标签需要我们自行定义。 XML被设计为具有自我描述性。 XML是W3C的推荐标准。 W3School官
用户1174963
2018/01/17
2.1K0
Python爬虫(十二)_XPath与lxml类库
Python的Xpath介绍和语法详解
XPath是一门在XML和HTML文档中查找信息的语言,可以用来在XML和HTML文档中对元素和属性进行遍历
Lansonli
2021/10/09
4.2K0
python爬虫入门(三)XPATH和BeautifulSoup4
 XML和XPATH 用正则处理HTML文档很麻烦,我们可以先将 HTML文件 转换成 XML文档,然后用 XPath 查找 HTML 节点或元素。 XML 指可扩展标记语言(EXtensible M
zhang_derek
2018/04/11
2.5K0
python爬虫入门(三)XPATH和BeautifulSoup4
数据提取-XPath
官网 (opens new window) http://lxml.de/index.html
小小杰啊
2022/12/21
1.4K0
Python爬虫之数据提取-lxml模块
数据提取-lxml模块 知识点 了解 lxml模块和xpath语法的关系 了解 lxml模块的使用场景 了解 lxml模块的安装 了解 谷歌浏览器xpath helper插件的安装和使用 掌握 xpath语法-基础节点选择语法 掌握 xpath语法-节点修饰语法 掌握 xpath语法-其他常用语法 掌握 lxml模块中使用xpath语法定位元素提取属性值或文本内容 掌握 lxml模块中etree.tostring函数的使用 ---- 1. 了解 lxml模块和xpath语法 对html或xml形式的文本提
海仔
2020/09/08
2.1K0
Python爬虫之数据提取-lxml模块
初学者的20个爬虫经典案例视频_李昌钰水门事件20集大经典案例
链接:aHR0cHM6Ly9iai5mYW5nLmxpYW5qaWEuY29tL2xvdXBhbi8=
全栈程序员站长
2022/11/07
1.2K0
初学者的20个爬虫经典案例视频_李昌钰水门事件20集大经典案例
学爬虫利器Xpath,看这一篇就够了(建议收藏)
上一篇文章主要给大家介绍了Xpath的基础知识,大家看完之后有没有收获呢?按照计划,今天就结合示例给大家介绍如何使用Xpath?
stormwen
2019/08/05
1.3K0
Python爬虫爬取豆瓣电影之数据提取值
工具:Python 3.6.5、PyCharm开发工具、Windows 10 操作系统、谷歌浏览器
py3study
2020/01/19
8550
Python爬虫爬取豆瓣电影之数据提取值
Python:XPath与lxml类库
W3School官方文档:http://www.w3school.com.cn/xml/index.asp
Lansonli
2021/10/09
1.6K0
lxml与pyquery解析html
首先来了解一下lxml,很多常用的解析html的库都用到了lxml这个库,例如BeautifulSoup、pyquery。
全栈程序员站长
2022/09/05
1.6K0
lxml与pyquery解析html
一起学爬虫——使用xpath库爬取猫眼电
之前分享了一篇使用requests库爬取豆瓣电影250的文章,今天继续分享使用xpath爬取猫眼电影热播口碑榜
py3study
2020/01/21
9240
Python3解析库lxml
lxml是python的一个解析库,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高 XPath,全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜寻XML文档的,但是它同样适用于HTML文档的搜索 XPath的选择功能十分强大,它提供了非常简明的路径选择表达式,另外,它还提供了超过100个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等,几乎所有我们想要定位的节点,都可以用XPath来选择 XPath于1999年11月16日成为W3C标准,它被设计为供XSLT、XPointer以及其他XML解析软件使用,更多的文档可以访问其官方网站:https://www.w3.org/TR/xpath/
菲宇
2019/06/12
1.7K0
一日一技:一个Python爬虫案例,带你掌握xpath数据解析方法!
2.调用etree对象中的xpath方法结合xpath表达式实现标签的定位和内容的捕获。
用户8949263
2022/04/08
4130
一日一技:一个Python爬虫案例,带你掌握xpath数据解析方法!
爬虫系列(8)数据提取--扩展三种方法。
w3c http://www.w3school.com.cn/xpath/index.asp
野原测试开发
2019/07/10
2K0
爬虫系列(8)数据提取--扩展三种方法。
Python3网络爬虫实战-28、解析库
上一节我们实现了一个最基本的爬虫,但提取页面信息时我们使用的是正则表达式,用过之后我们会发现构造一个正则表达式还是比较的繁琐的,而且万一有一点地方写错了就可能会导致匹配失败,所以使用正则来提取页面信息多多少少还是有些不方便的。
py3study
2020/01/06
2.4K0
相关推荐
python爬虫之lxml库xpath的基本使用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验