【python爬虫】xpath使用说明

2023-12-28 11:48:46

XPath 可以在XML文档中查找信息,支持HTML,可以用来提取信息。可以把标签文本看作一个树状图,最顶层是html,第二层是head和body,body的下面是许多div,每个div可以用/[@属性=属性名]来进一步细分,也可以通过/@属性来获取对应的信息,提取双标签中的文字则可以用/text()。

安装库

pip3 install lxml

基本使用

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)  
result = etree.tostring(html)  
print(result.decode("utf-8"))

从下面的结果来看,这里的html其实就是一个python对象,etree.tostring(html)则补全了html缺胳膊少腿的标签。

输出结果:

<Element html at 0x39e58f0>  
<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>

语法

选取节点

XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。

下面列出了最有用的路径表达式:

表达式描述
nodename选取此节点的所有子节点。
/表示子级范围
//表示子孙后代范围
.选取当前节点。
选取当前节点的父节点。
@根据属性具体判断某一个标签,可以通过 标签名[属性值判断式] 来定位,

示例

在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:

路径表达式结果
bookstore选取 bookstore 元素的所有子节点。
/bookstore选取元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
bookstore/book选取属于 bookstore 的子元素的所有 book 元素。
//book选取所有 book 子元素,而不管它们在文档中的位置。
bookstore//book选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang选取名为 lang 的所有属性。

谓语(Predicates)

谓语被嵌在方括号中,用来查找某个特定的节点或者包含某个指定的值的节点。

顺序定位

  1. 方式一:[1]
    通配标签返回的是一个列表,里面为空或者一些元素。
    xpath支持取具体值, 例如去列表的第一个元素,[1]就可以拿到;第二个值就是[2]。
    注意列表的下角标从1开始,不像python那样从0开始
  2. 方式二:position()
    position函数会返回当前的位置值,拿到值之后就可以对值进行判断选取。
    举例: 选取当前位置下的所有div标签,然后去掉第一个,取出从2开始,一直到最后 一个div标签。
    .//div[position()>1]
  3. 方式三:last()
    这个是最简单的,就是取列表的最后一个元素
    举例:
    .//div[last()]

示例

在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

路径表达式结果
/bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()]选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1]选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()??]选取最前面的两个属于 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。

选取未知节点

XPath 通配符可用来选取未知的 XML 元素。

通配符描述
*匹配任何元素节点。
@*匹配任何属性节点。
node()匹配任何类型的节点。

示例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式结果
/bookstore/*选取 bookstore 元素的所有子元素。
//*选取文档中的所有元素。
//title[@*]选取所有带有属性的 title 元素。

选取若干路径

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

示例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式结果
//book/title | //book/price选取 book 元素的所有 title 和 price 元素。
//title | //price选取文档中的所有 title 和 price 元素。
/bookstore/book/title | //price选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。

与或非

通过与或非进行更严格的筛选

逻辑?非?
关键字?andornot()?
示例?.//div[@id and @class]?.//div[@id or @class]?.//div[not(@id)]?
示例解释?同时拥有id和class属性的div有id或者class属性的div没有id属性的
div

常用函数

contains(属性名,值)

匹配包含对应值的标签或数据

response.xpath('//a[contains(text(),"Next >")]')
response.xpath('.//div[contains(@class,"content")]')

获取某个标签的内容(基本使用),注意,获取a标签的所有内容,a后面就不用再加正斜杠,否则报错。

text()

获取文本
写法一

html = etree.HTML(wb_data)
html_data = html.xpath('/html/body/div/ul/li/a')
print(html)
for i in html_data:
	print(i.text)

输出:

<Element html at 0x12fe4b8>
first item
second item
third item
fourth item
fifth item

写法二
直接在需要查找内容的标签后面加一个/text()就行

html = etree.HTML(wb_data)
html_data = html.xpath('/html/body/div/ul/li/a/text()')
print(html)
for i in html_data:
	print(i)

输出:

<Element html at 0x138e4b8>
first item
second item
third item
fourth item
fifth item

parse(html文件路径)

打开读取html文件

#使用parse打开html的文件
html = etree.parse('test.html')
html_data = html.xpath('//*')#打印是一个列表,需要遍历
print(html_data)
for i in html_data:
	print(i.text)

将文本转码

html = etree.parse('test.html')
html_data = etree.tostring(html,pretty_print=True)
res = html_data.decode('utf-8')
print(res)

示例

打印指定路径下a标签的属性

可以通过遍历拿到某个属性的值,查找标签的内容

html = etree.HTML(wb_data)
html_data = html.xpath('/html/body/div/ul/li/a/@href')
for i in html_data:
	print(i)

相对路径匹配

下面我们查找相对路径,例如,查找所有li标签下的a标签内容。

html = etree.HTML(wb_data)
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

使用相对路径,查找一下相对路径下li标签下的a标签下的href属性的值,注意,a标签后面需要双//。

html = etree.HTML(wb_data)
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

相对路径下跟绝对路径下查特定属性的方法类似,也可以说相同。

html = etree.HTML(wb_data)
html_data = html.xpath('//li/a[@href="link2.html"]')
print(html_data)
for i in html_data:
	print(i.text)

打印:

[<Element a at 0x216e468>]
second item

查找最后一个li标签里的a标签的href属性

html = etree.HTML(wb_data)
html_data = html.xpath('//li[last()]/a/text()')
print(html_data)
for i in html_data:
	print(i)

打印:

['fifth item']
fifth item

查找倒数第二个li标签里的a标签的href属性

html = etree.HTML(wb_data)
html_data = html.xpath('//li[last()-1]/a/text()')
print(html_data)
for i in html_data:
	print(i)

打印:

['fourth item']
fourth item

文章来源:https://blog.csdn.net/qq_40951951/article/details/135240586
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。