XPath解析(一)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: XPath解析(一)

XPath 概述
XPath是 XML路径语言,全名为“XML Path Language“,是一门可以在XML文件中查找信息的语言。不仅可以实现XML文件的搜索,还可以在HTML文件中进行搜索。XPath常用路径表达式:
image.png

XPath常用路径表达式及描述
XPath的解析操作
lxml模块可以解析HTML与XML,并且支持XPath解析方式。

解析HTML
• 1. parse()方法

parse()方法主要用于实现解析本地的HTML文件,示例代码如下:

#_*_coding:utf-8_*_
# 作者      :liuxiaowei
# 创建时间   :2/4/22 5:58 AM
# 文件      :parse()方法.py
# IDE      :PyCharm

from lxml import etree    # 导入etree子模块
parser = etree.HTMLParser()  # 创建HTMLParser对象
html = etree.parse('demo.html',parser=parser)  # 解析demo.html文件
html_txt = etree.tostring(html,encoding = "utf-8")   # 转换字符串类型,并进行编码
print(html_txt.decode('utf-8'))    # 打印解码后的HTML代码

程序运行结果如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- saved from url=(0038)http://sck.rjkflm.com:666/spider/auth/ --><html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>标题文档</title>
</head>

<body>
<img src="./demo_files/logo1.png" />
<br />
hello 明日科技 ~
</body></html>

• 2. HTML()方法

etree子模块还提供了一个HTML()方法,该方法可以实现解析字符串类型的HTML代码。示例代码如下:

#_*_coding:utf-8_*_
# 作者      :liuxiaowei
# 创建时间   :2/4/22 6:21 AM
# 文件      :解析字符串类型的HTML代码.py
# IDE      :PyCharm

# 导入etree子模块
from lxml import etree

# 定义HTML字符串
html_str = '''<title>标题文档</title>
</head>

<body>
<img src="./demo_files/logo1.png" />
<br />
hello 明日科技 ~
</body></html>'''

# 解析HTML字符串
html = etree.HTML(html_str)

# 转换字符串类型,并进行编码
html_txt = etree.tostring(html, encoding = 'utf-8')
print(html_txt.decode('utf-8'))

程序运行结果如下:

<html><head><title>标题文档</title>
</head>

<body>
<img src="./demo_files/logo1.png"/>
<br/>
hello 明日科技 ~
</body></html>

解析服务器返回的HTML代码,实际开发中,发送网络请求后,多数情况下都会将返回的响应结果转换为字符串类型,如果返回的结果是HTML代码,则需要使用HTML()方法来进行解析。示例代码如下:

#_*_coding:utf-8_*_
# 作者      :liuxiaowei
# 创建时间   :2/4/22 6:28 AM
# 文件      :解析服务器返回的HTML代码.py
# IDE      :PyCharm

from lxml import etree    # 导入etree子模块
import requests          # 导入requests模块
from requests.auth import HTTPBasicAuth  # 导入HTTPBasicAuth类
# 定义请求地址
url = 'http://sck.rjkflm.com:666/spider/auth/'
ah = HTTPBasicAuth('admin','admin')      # 创建HTTPBasicAuth对象,参数为用户名与密码
response = requests.get(url=url,auth=ah) # 发送网络请求
if response.status_code==200:            # 如果请求成功
    html = etree.HTML(response.text)    # 解析html字符串
    html_txt = etree.tostring(html,encoding = "utf-8")   # 转换字符串类型,并进行编码
    print(html_txt.decode('utf-8'))    # 打印解码后的HTML代码

程序运行结果如下:
image.png

说 明

图中红框内的" "表示Unicode编码的回车字符

获取所有节点
在获取HTML代码中的所有节点时,可以使用"//*"的方式,示例代码如下:

#_*_coding:utf-8_*_
# 作者      :liuxiaowei
# 创建时间   :2/4/22 7:04 AM
# 文件      :*"获取HTML代码的所有节点.py
# IDE      :PyCharm

from lxml import etree    # 导入etree子模块
# 定义html字符串
html_str = '''
<div class="level_one on">
<ul>
<li> <a href="/index/index/view/id/1.html" title="什么是Java" class="on">什么是Java</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="Java的版本">Java的版本</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="Java API文档">Java API文档</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="JDK的下载">JDK的下载</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="JDK的安装">JDK的安装</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="配置JDK">配置JDK</a> </li>
</ul>
</div>
'''
html = etree.HTML(html_str)    # 解析html字符串
node_all = html.xpath('//*')   # 获取所有节点
print('数据类型:',type(node_all))          # 打印数据类型
print('数据长度:',len(node_all))           # 打印数据长度
print('数据内容:',node_all)                # 打印数据内容
# 通过推导式打印所有节点名称,通过节点对象.tag获取节点名称
print('节点名称:',[i.tag for i in node_all])

程序运行结果如下:

数据类型: <class 'list'>
数据长度: 16
数据内容: [<Element html at 0x7fd73360f280>, <Element body at 0x7fd73376b640>, <Element div at 0x7fd73376b680>, <Element ul at 0x7fd73376b6c0>, <Element li at 0x7fd73376b700>, <Element a at 0x7fd73376b780>, <Element li at 0x7fd73376b7c0>, <Element a at 0x7fd73376b800>, <Element li at 0x7fd73376b840>, <Element a at 0x7fd73376b740>, <Element li at 0x7fd73376b880>, <Element a at 0x7fd73376b8c0>, <Element li at 0x7fd73376b900>, <Element a at 0x7fd73376b940>, <Element li at 0x7fd73376b980>, <Element a at 0x7fd73376b9c0>]
节点名称: ['html', 'body', 'div', 'ul', 'li', 'a', 'li', 'a', 'li', 'a', 'li', 'a', 'li', 'a', 'li', 'a']

获取HTML代码中所有指定名称的节点,可以在“//”的后面添加节点的名称。以获取所有“li“节点为例,关键代码如下:

#_*_coding:utf-8_*_
# 作者      :liuxiaowei
# 创建时间   :2/4/22 7:49 AM
# 文件      :获取指定名称的节点.py
# IDE      :PyCharm

from lxml import etree    # 导入etree子模块
# 定义html字符串
html_str = '''
<div class="level_one on">
<ul>
<li> <a href="/index/index/view/id/1.html" title="什么是Java" class="on">什么是Java</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="Java的版本">Java的版本</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="Java API文档">Java API文档</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="JDK的下载">JDK的下载</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="JDK的安装">JDK的安装</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="配置JDK">配置JDK</a> </li>
</ul>
</div>
'''
html = etree.HTML(html_str)    # 解析html字符串,html字符串为上一示例的html字符串
li_all = html.xpath('//li')   # 获取所有li节点
print('所有li节点',li_all)    # 打印所有li节点
print('获取指定li节点:',li_all[1])  # 打印指定li节点
li_txt = etree.tostring(li_all[1],encoding = "utf-8")   # 转换字符串类型,并进行编码
# 打印指定节点的HTML代码
print('获取指定节点HTML代码:',li_txt.decode('utf-8'))

程序运行结果如下:

所有li节点 [<Element li at 0x7fd6ca76b300>, <Element li at 0x7fd6ca76b340>, <Element li at 0x7fd6ca76b380>, <Element li at 0x7fd6ca76b3c0>, <Element li at 0x7fd6ca76b400>, <Element li at 0x7fd6ca76b480>]
获取指定li节点: <Element li at 0x7fd6ca76b340>
获取指定节点HTML代码: <li> <a href="javascript:" onclick="login(0)" title="Java的版本">Java的版本</a> </li>

如果需要获取一个节点中的直接子节点可以使用“/”,例如获取li节点中所有子节点a,可以使用“//li/a”的方式进行获取,示例代码如下:

#_*_coding:utf-8_*_
# 作者      :liuxiaowei
# 创建时间   :2/4/22 8:02 AM
# 文件      :"获取一个节点中的直接子节点.py
# IDE      :PyCharm

from lxml import etree    # 导入etree子模块
# 定义html字符串
html_str = '''
<div class="level_one on">
<ul>
<li>
    <a href="/index/index/view/id/1.html" title="什么是Java" class="on">什么是Java</a>
    <a>Java</a> 
</li>
<li> <a href="javascript:" οnclick="login(0)" title="Java的版本">Java的版本</a> </li>
<li> <a href="javascript:" οnclick="login(0)" title="Java API文档">Java API文档</a> </li>
</ul>
</div>
'''
html = etree.HTML(html_str)    # 解析html字符串
a_all = html.xpath('//li/a')   # 获取li节点中所有子节点a
print('所有子节点a',a_all)    # 打印所有a节点
print('获取指定a节点:',a_all[1])  # 打印指定a节点
a_txt = etree.tostring(a_all[1],encoding = "utf-8")   # 转换字符串类型,并进行编码
# 打印指定节点的HTML代码
print('获取指定节点HTML代码:',a_txt.decode('utf-8'))

程序运行结果如下:

所有子节点a [<Element a at 0x7f7c2c76b340>, <Element a at 0x7f7c2c76b380>, <Element a at 0x7f7c2c76b3c0>, <Element a at 0x7f7c2c76b400>]
获取指定a节点: <Element a at 0x7f7c2c76b380>
获取指定节点HTML代码: <a>Java</a>

使用"//"实现获取直接子孙节点,以获取ul节点中所有子孙节点a为例,示例代码如下:

#_*_coding:utf-8_*_
# 作者      :liuxiaowei
# 创建时间   :2/4/22 9:47 AM
# 文件      :实现获取子孙节点.py
# IDE      :PyCharm

from lxml import etree    # 导入etree子模块
# 定义html字符串
html_str = '''
<div class="level_one on">
<ul>
<li>
    <a href="/index/index/view/id/1.html" title="什么是Java" class="on">什么是Java</a>
    <a>Java</a> 
</li>
<li> <a href="javascript:" οnclick="login(0)" title="Java的版本">Java的版本</a> </li>
<li> 
    <a href="javascript:" οnclick="login(0)" title="Java API文档">
        <a>a节点中的a节点</a>
    </a>
</li>
</ul>
</div>
'''
html = etree.HTML(html_str)    # 解析html字符串
a_all = html.xpath('//ul//a')   # 获取ul节点中所有子孙节点a
print('所有子节点a',a_all)    # 打印所有a节点
print('获取指定a节点:', a_all[4])  # 打印指定a节点
a_txt = etree.tostring(a_all[4], encoding = "utf-8")   # 转换字符串类型,并进行编码
# 打印指定节点的HTML代码
print('获取指定节点HTML代码:', a_txt.decode('utf-8'))

程序运行结果如下:

所有子节点a [<Element a at 0x7ff605767400>, <Element a at 0x7ff605767440>, <Element a at 0x7ff605767480>, <Element a at 0x7ff6057674c0>, <Element a at 0x7ff605767500>]
获取指定a节点: <Element a at 0x7ff605767500>
获取指定节点HTML代码: <a>a节点中的a节点</a>

说 明

在获取ul子孙节点时,如果使用“//ul/a“的方式获取,是无法匹配任何结果的。因为“/”用来获取直接子节点,ul的直接子节点为li,并没有a节点,所以无法匹配。

接下文 XPath解析(二)https://developer.aliyun.com/article/1615872

相关文章
|
开发者
数据解析之Xpath解析(超详细定位)2
数据解析之Xpath解析(超详细定位)2
77 0
数据解析之xpath 太6了
数据解析之xpath 太6了
|
2月前
|
索引 Python
|
2月前
|
Java
XPath解析(二)
XPath解析(二)
|
5月前
|
XML 数据采集 前端开发
四:《智慧的网络爬虫》— 数据解析之xpath解析
本篇文章主要讲述了数据解析中的xpath解析,及相对路径的定位语法。最后以爬取豆瓣top250首页作为示例总结
97 5
四:《智慧的网络爬虫》—  数据解析之xpath解析
|
5月前
|
XML 数据格式 Python
Python使用xpath对解析内容进行数据提取
在前面的文章当中,已经教大家如何去获取我们需要的数据原文内容,今天就介绍一个用于提取所需数据的方法之一xpath。在后续会讲解bs4(beautifulsoup),re正则表达式。
|
5月前
|
XML 数据格式 Python
Python使用xpath对解析内容进行数据提取
今天就介绍一个用于提取所需数据的方法之一xpath。在后续会讲解bs4(beautifulsoup),re正则表达式。
|
5月前
|
XML Web App开发 JavaScript
解析神器Xpath详解+实战
解析神器Xpath详解+实战
|
索引 Python
【Python】数据解析—Xpath解析
【Python】数据解析—Xpath解析
66 0
|
XML 数据格式 开发者
数据解析之Xpath解析(超详细定位)1
数据解析之Xpath解析(超详细定位)1
253 0

推荐镜像

更多