我要爬爬虫(7)-xpath解析库

常用符号

/ 直接子节点
// 所有子孙节点
. 当前节点
.. 当前节点的父节点
@ 属性值
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>&#13;
    <ul>&#13;
        <li class="item-0"><a href="link1.html">first time</a> </li>&#13;
        <li class="item-1"><a href="link2.html">second time</a> </li>&#13;
        <li class="item-inactive"><a href="link3.html">third time</a> </li>&#13;
        <li class="item-1"><a href="link4.html">fouth time</a> </li>&#13;
        <li class="item-0"><a href="link5.html">fifth time</a> </li>&#13;
    </ul>&#13;
</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节点的后面第二个节点

猜你喜欢

转载自blog.csdn.net/qq_18831501/article/details/80997710