提取数据之一:xpath
Xpath的使用
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。
下面列出了最有用的路径表达式:
表达式 | 描述 | 示例 | 结果 |
---|---|---|---|
nodename | 选取此节点的所有子节点。 | bookstore | 选取 bookstore 元素的所有子节点。 |
/ | 如果在最前面,代表从根节点选取。否则选取某节点下的某个节点。 | /bookstore | 选取根元素bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
// | 从全局节点中选择节点,而不考虑它们的位置。 | //book | 选取所有 book 元素。 |
. | 选取当前节点。 | ||
.. | 选取当前节点的父节点。 | ||
@ | 选取属性。 | //book[@price] | 选取含有price属性的book节点 |
1:谓语(Predicates)
谓语用来查找某个特定的节点或者包含某个指定的值的节点。谓语被嵌在 [ ]中。
PS:下标从1开始
路径表达式 | 结果 |
---|---|
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()❤️] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//book[@lang] | 选取所有拥有 lang 属性的 book 元素。 |
//book[@price='10'] | 选取所有 book 元素,并且这些book元素的price属性值等于10 |
/bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
2:选取未知节点
通配符 | 描述 | 示例 | 结果 |
---|---|---|---|
* | 匹配任何元素节点。 | /bookstore/* | 选取 bookstore 元素的所有子元素。 |
@* | 匹配任何属性节点。 | //title[@*] | 选取所有带有属性的 title 元素。 |
3:选取若干路径
通过在路径表达式中使用“|”运算符,您可以选取若干个路径。
路径表达式 | 结果 |
---|---|
//book/title | //book/price | 选取 book 元素的所有 title 和 price 元素。 |
//title | //price | 选取文档中的所有 title 和 price 元素。 |
/bookstore/book/title | //price | 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。 |
4:xpath语法:
使用方式:
使用//获取整个页面当中的元素,然后写标签名,然后再写谓词进行提取。比如:
//div[@class='abc']
需要注意的知识点:
-
/和//的区别:/代表只获取直接子节点。//获取子孙节点。一般//用得比较多。当然也要视情况而定。
-
contains:有时候某个属性中包含了多个值,那么可以使用
contains
函数。示例代码如下://div[contains(@class,'job_detail')]
-
谓词中的下标是从1开始的,不是从0开始的。
-
解析html字符串:使用
lxml.etree.HTML
进行解析。示例代码如下:
from lxml import etree #导入etree模块
test=''' HTML代码'''
htmlElement = etree.HTML(text) #HTML(),返回一个Element对象
result=etree.tostring(htmlElement) #tostring()输出修正后的html代码,但是结果是bytes类型
print(result.decode('utf-8')) #转成str类型
5.解析html文件:使用lxml.etree.parse
进行解析。示例代码如下:
from lxml import etree
html = etree.parse("./tencent.html",etree.HTMLParser()) #parse()
result=etree.tostring(html)
print(result.decode('utf-8'))
6.这个函数etree.parse()默认使用的是XML
解析器,所以如果碰到一些不规范的HTML
代码的时候就会解析错误,这时候就要自己创建HTML
解析器。
parser = etree.HTMLParser(encoding='utf-8') #设置html解析器
htmlElement = etree.parse("lagou.html",parser=parser)
print(etree.tostring(htmlElement, encoding='utf-8').decode('utf-8'))
lxml结合xpath注意事项:
-
使用
xpath
语法。应该使用Element.xpath
方法。来执行xpath的选择。示例代码如下:trs = html.xpath("//tr[position()>1]")
xpath函数
返回来的永远是一个列表。 -
获取某个标签的属性值:
href = html.xpath("//a/@href") # 获取a标签的href属性对应的值
-
获取文本,是通过
xpath
中的text()
函数。示例代码如下:address = tr.xpath("./td[4]/text()")[0]
-
在某个标签下,再执行xpath函数,获取这个标签下的子孙元素,那么应该在斜杠之前加一个点,代表是在当前元素下获取。示例代码如下:
address = tr.xpath("./td[4]/text()")[0] img_url=div.xpath('.//img/@src')
-
父节点 ..
result=html.xpath('//a[@href='link1.html']/../@class') #先获取href属性为link1.html的a节点,然后获取其父节点,最后获取其class属性值
-
属性匹配----使用@进行属性过滤
.xpath('//li[@class="item-0"]') #获取所有class="item-0"的li标签,返回列表
-
属性的-多值匹配
.xpath('//li[contains(@class),"属性值"]') #contains()方法,第一个参数传入属性名称,第二个参数传入属性值
-
多属性 -匹配
.xpath('//li[contains(@class),"属性值" and @name="属性值"]') .xpath('//li[@class="属性值" and @name="属性值"]') and or < ><= >= 等等