该篇文章用于记录Xpath常用的一些规则以及学习笔记
安装库
pip install lxml
导入库
from lmxl import etree
解析方式
从本地HTML文档加载到etree
import requests
from lxml import etree
parser = etree.HTMLParser()
html = etree.parse('data.html',parser)
data = html.xpath("//div[@class='title']/p")
for i in range(len(data)):
h = data[index].get('href')
t = data[index].text
print(h,t)
从网页源代码加载到etree
import requests
from lxml import etree
response = requests.get(url)
tree = etree.HTML(response.text)
基础语法
以下是xpath解析过程中常见的一些语法
符号含义
表达式 | 描述 | 实例 | 备注 |
nodename | 选取该节点的所有子节点 | xpath("//div") | 选取div节点的所有子元素 |
| | 和 | xpath("//div/p|a") | 选取所有div元素下的p元素和a元素 / 从根节点选取 xpath("/div") 从根节点上选取div元素 |
// | 选取HTML所有的当前节点 | xpath("//div") | 选取HTML中所有的div元素 |
. | 选取当前节点 | xpath("./") | 选取当前节点下的div元素 |
.. | 选取当前节点的父节点 | xpath("..") | 回到上一个元素 |
@ | 选取属性 | xpath("//@class") | 选取所有的class属性 |
常见语法
表达式 | 含义 |
//div/a[1] | 选取所有div元素下的第一个a子元素 |
//div/a[last()] | 选取所有div元素下的最后一个a子元素 |
//div/a[last()-1] | 选取所有div元素下的倒数第二个a子元素 |
//div/a[position()<3] | 选取所有div元素下的前两个a子元素 |
//div[@class] | 选取带class属性的所有div元素 |
//div[@class='name'] | 选取带class=‘name’属性的所有div元素 |
//div/p[price>35.00] | 选取所有div元素下的p子元素,且p下的price子元素的值大于35.00 |
//div[@class='name']/a[2]//text() | 选取带class=‘name’属性的所有div元素下的第二个a子元素下的所有文本 |
//div/p/text()|a/li//text() | 选取div元素下的p子元素的文本和a子元素下的li子元素下的所有文本 |
模糊匹配语法
通配符 | 含义 | 实例 | 含义 |
* | 匹配任何元素节点 | /div/* | 选取div元素下的所有子元素 |
@* | 匹配任何属性节点 | /div[@*] | 选取所有带属性的div元素 |
node() | 匹配任何类型的节点 | ||
//* | 选取文档中所有的元素 |
函数语法
函数 | 用途 | 实例 | 含义 |
and | 和 | xpath(‘//div[contains(@id,”a”) and contains(@id,”p”)]’) | 选取id值包含a和p的div节点 |
text() | 文本 | xpath(‘//div[contains(text(),”test”)]’) | 获取文本 |
contains | 获取包含xxx的元素 | xpath(‘//div/p[contains(@id,”test”)]’) | 选取div元素下包含test的id值的p标签 |
starts-with | 获取以xxx开头的元素 | xpath(‘//div[stars-with(@class,”test”)]’) | 选取div元素下以test开头的class属性的p标签 |
注意事项:
etree解析输出的类型为bytes,可通过etree.tostring()转换为字符串
html = etree.xpath(text)
print(etree.tostring(html,encoding='utf-8').decode("utf-8"))