常用符号
/ 直接子节点
// 所有子孙节点
. 当前节点
.. 当前节点的父节点
@ 属性值
contains 属性包括
lxml库的使用
对于下面这段html文本source.html
<div>
<ul>
<li class ="item-0"><a href="link1.html">first time</a> </li>
<li class ="item-1"><a href="link2.html">second time</a> </li>
<li class ="item-inactive"><a href="link3.html">third time</a> </li>
<li class ="item-1"><a href="link4.html">fouth time</a> </li>
<li class ="item-0"><a href="link5.html">fifth time</a>
</ul>
</div>
直接解析html文本
from lxml import etree
#HTML方法传入html文本构造xpath解析对象,并可自动修复缺省格式
html=etree.HTML('XXXXXXXXXX')
#tostring转换成bytes
result=etree.tostring(html)
#decode转换成string
print(result.decode('gbk'))
#解码之后可以实现换行输出,utf-8或gbk都行
结果如下
<html><body><div>
<ul>
<li class="item-0"><a href="link1.html">first time</a> </li>
<li class="item-1"><a href="link2.html">second time</a> </li>
<li class="item-inactive"><a href="link3.html">third time</a> </li>
<li class="item-1"><a href="link4.html">fouth time</a> </li>
<li class="item-0"><a href="link5.html">fifth time</a>
</li></ul>
</div>
</body></html>
其实就是个补全格式的操作。
也可对html文件进行解析。
html=etree.parse('source.html',parser=etree.HTMLParser())
result=etree.tostring(html)
print(result.decode('gbk'))
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><div>
<ul>
<li class="item-0"><a href="link1.html">first time</a> </li>
<li class="item-1"><a href="link2.html">second time</a> </li>
<li class="item-inactive"><a href="link3.html">third time</a> </li>
<li class="item-1"><a href="link4.html">fouth time</a> </li>
<li class="item-0"><a href="link5.html">fifth time</a> </li>
</ul>
</div></body></html>
多了个DOCTYPE的声明,其他一样。
取节点
html.xpath('//*')
取得所有子孙节点
列表形式返回所有节点
[<Element html at 0x1626ad130c8>,
<Element body at 0x1626ac5d648>,
<Element div at 0x1626ad1c108>,
<Element ul at 0x1626ad1cfc8>,
<Element li at 0x1626ad1c788>,
<Element a at 0x1626ad1c8c8>,
<Element li at 0x1626ad1c648>,
<Element a at 0x1626ad1c848>,
<Element li at 0x1626ad1c388>,
<Element a at 0x1626ad1c3c8>,
<Element li at 0x1626ad1c208>,
<Element a at 0x1626ad1c188>,
<Element li at 0x1626ad1c6c8>,
<Element a at 0x1626ad1c688>]
//li
取得所有li节点
//li/a
取得所有li节点下的直接a节点
//a[@href="link4.html"]/../@class
取得所有满足href=“link4.html”的a节点的父节点的class属性
li[@class="item-0"]/text()
这里取不到任何值
结果[' ', '\n ']
因为li节点的直接子节点没有文本,只有a节点和空格,以及构造xpath对象时添加的换行符。
对于<li class="li li-first"><a href="link.html"><a/><li/>
这里li节点的class属性有两个值li li-first,所以用[@class='li']
是取不到该节点的,应该使用[contains(@class,'li')]
,这样属性值里包含即可匹配到。
//li[contains(@class,"li") and @name="item"]/a/text()
这里使用and并列查找条件。
//li[1]
下标1即取第一个节点,并非第二个。
//li[last()]
最后一个节点
//li[position()<3]
下标小于3,即第一,第二个节点。
//li[last()-2]
倒数第三个节点
节点轴
ancestor 祖先节点
attribute 属性值
child 子节点
decedent 子孙节点
following 后面的节点
following-sibling 后面的同级节点
//li[1]/following::*2
第一个li节点的后面第二个节点