【python爬虫自学笔记】-----xpath 用法

简介

xpath是一门在xml文档中查找信息的语言。xpath可以用来在xml文档中对元素和属性进行遍历,xpath是W3C XSLT标准的主要元素,并且XQuery和XPointer都构建于xpath表达之上。

安装模块lxml

pip install lxml

语法

表达式描述
nodename选取此节点的所有子节点。
/从根节点选取。
//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
.选取当前节点。
..选取当前节点的父节点。
@选取属性。
  • xml.xpath(“bookstore”) 表示选取 bookstore 元素的所有子节点
  • xml.xpath(“/bookstore”) 表示选取根元素 bookstore。
  • xml.xpath(“bookstore/book”) 选取属于 bookstore 的子元素的所有 book 元素。
  • xml.xpath(“//book”) 选取所有 book 子元素,而不管它们在文档中的位置。
  • xml.xpath(“bookstore//book”) 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
  • xml.xpath(“//@lang”) 选取名为 lang 的所有属性。
路径表达式结果
/bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()]选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1]选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3]选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang]选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang=’eng’]选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00]选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。
通配符描述
*匹配任何元素节点。
@*匹配任何属性节点。
node()匹配任何类型的节点。
路径表达式结果
/bookstore/*选取 bookstore 元素的所有子元素。
//*选取文档中的所有元素。
//title[@*]选取所有带有属性的 title 元素。

选取若干路径

通过在路径表达式中使用“|”运算符,您可以选取若干个路径。

  • //book/title | //book/price 选取 book 元素的所有 title 和 price 元素。
  • //title | //price 选取文档中的所有 title 和 price 元素。
  • /bookstore/book/title | //price 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。

轴可定义相对于当前节点的节点集。

轴名称结果
ancestor选取当前节点的所有先辈(父、祖父等)。
ancestor-or-self选取当前节点的所有先辈(父、祖父等)以及当前节点本身。
attribute选取当前节点的所有属性。
child选取当前节点的所有子元素。
descendant选取当前节点的所有后代元素(子、孙等)。
descendant-or-self选取当前节点的所有后代元素(子、孙等)以及当前节点本身。
following选取文档中当前节点的结束标签之后的所有节点。
namespace选取当前节点的所有命名空间节点。
parent选取当前节点的父节点。
preceding选取文档中当前节点的开始标签之前的所有节点。
preceding-sibling选取当前节点之前的所有同级节点。
self选取当前节点。

步的语法: 
轴名称::节点测试[谓语]

例子:

例子结果
child::book选取所有属于当前节点的子元素的 book 节点。
attribute::lang选取当前节点的 lang 属性。
child::*选取当前节点的所有子元素。
attribute::*选取当前节点的所有属性。
child::text()选取当前节点的所有文本子节点。
child::node()选取当前节点的所有子节点。
descendant::book选取当前节点的所有 book 后代。
ancestor::book选择当前节点的所有 book 先辈。
ancestor-or-self::book选取当前节点的所有 book 先辈以及当前节点(如果此节点是 book 节点)
child::*/child::price选取当前节点的所有 price 孙节点。

函数

1 starts-with函数

获取以xxx开头的元素 
例子:xpath(‘//div[stars-with(@class,”test”)]’)

2 contains函数

获取包含xxx的元素 
例子:xpath(‘//div[contains(@id,”test”)]’)

3 and

与的关系 
例子:xpath(‘//div[contains(@id,”test”) and contains(@id,”title”)]’)

4 text()函数

例子1:xpath(‘//div[contains(text(),”test”)]’) 
例子2:xpath(‘//div[@id=”“test]/text()’)

使用示例

(1)基本使用

from lxml import etree
wb_data = """
        <div>
            <ul>
                 <li class="item-0"><a href="link1.html">first item</a></li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-inactive"><a href="link3.html">third item</a></li>
                 <li class="item-1"><a href="link4.html">fourth item</a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a>
             </ul>
         </div>
        """
html = etree.HTML(wb_data)
print(html)

#html其实施一个python对象
<Element html at 0x13c66c4e208>

#使用tostring方法,补全少的标签
result = etree.tostring(html)
print(result.decode("utf-8"))

<html><body><div>
            <ul>
                 <li class="item-0"><a href="link1.html">first item</a></li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-inactive"><a href="link3.html">third item</a></li>
                 <li class="item-1"><a href="link4.html">fourth item</a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a>
             </li></ul>
         </div>
        </body></html>

(2)获取某个标签的内容

#获取某个标签的内容
#方法一
html_data = html.xpath('/html/body/div/ul/li/a')
for i in html_data:
    print(i.text)
#方法二
html_data = html.xpath('/html/body/div/ul/li/a/text()')
for i in html_data:
    print(i)

first item
second item
third item
fourth item
fifth item

(3)打开读取html文件

#打开读取html文件
html = etree.parse('test.html')
html_data = html.xpath('//*')
print(html_data)
for i in html_data:
    print(i.text)

D:\develop\Anaconda3\python.exe D:/thislove/pythonworkspace/blogspark/xpath_test.py
[<Element html at 0x2892d6fd108>, <Element body at 0x2892d6fd088>, <Element div at 0x2892d6fd1c8>, <Element ul at 0x2892d6fd208>, <Element li at 0x2892d6fd248>, <Element a at 0x2892d6fd2c8>, <Element li at 0x2892d6fd308>, <Element a at 0x2892d6fd348>, <Element li at 0x2892d6fd388>, <Element a at 0x2892d6fd288>, <Element li at 0x2892d6fd608>, <Element a at 0x2892d6fd648>, <Element li at 0x2892d6fd688>, <Element a at 0x2892d6fd6c8>]



    

            

                 
None
first item
None
second item
None
third item
None
fourth item
None
fifth item

Process finished with exit code 0

(4)打印指定路径下标签的属性

#打印指定路径下a标签的属性
html_data = html.xpath('/html/body/div/ul/li/a/@href')
for i in html_data:
    print(i)

link1.html
link2.html
link3.html
link4.html
link5.html

(5)使用xpath拿到的是ElementTree对象,如果需要查找内容,需要遍历拿到数据的列表。

#查找绝对路径下a标签属性等于link2.html的内容
html_data = html.xpath('/html/body/div/ul/li/a[@href="link2.html"]/text()')
print(html_data)
for i in html_data:
    print(i)

['second item']
second item

(6)使用相对路径进行查找

#相对路径
html_data = html.xpath('//li/a/text()')
print(html_data)
for i in html_data:
    print(i)

['first item', 'second item', 'third item', 'fourth item', 'fifth item']
first item
second item
third item
fourth item
fifth item

(7)查找相对路径下标签的属性值,标签后使用//

#查找相对路径下标签下的属性值,标签后使用//
html_data = html.xpath('//li/a//@href')
print(html_data)
for i in html_data:
    print(i)

['link1.html', 'link2.html', 'link3.html', 'link4.html', 'link5.html']
link1.html
link2.html
link3.html
link4.html
link5.html

(8)查找相对路径下特定属性的值

#相对路径下查找特定属性值
html_data = html.xpath('//li/a[@href="link2.html"]')
print(html_data)
for i in html_data:
    print(i.text)

[<Element a at 0x2dd0692e248>]
second item

(9)查找最后一个li标签中a标签的值

#查找最后一个li标签里的a标签的内容值
html_data = html.xpath('//li[last()]/a/text()')
print(html_data)
for i in html_data:
    print(i)

['fifth item']
fifth item

参考:https://blog.csdn.net/u013332124/article/details/80621638

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值