提取数据之一: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']

需要注意的知识点:

  1. /和//的区别:/代表只获取直接子节点。//获取子孙节点。一般//用得比较多。当然也要视情况而定。

  2. contains:有时候某个属性中包含了多个值,那么可以使用contains函数。示例代码如下:

    //div[contains(@class,'job_detail')]
    
  3. 谓词中的下标是从1开始的,不是从0开始的。

  4. 解析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注意事项:

  1. 使用xpath语法。应该使用Element.xpath方法。来执行xpath的选择。示例代码如下:

    trs = html.xpath("//tr[position()>1]")
    

    xpath函数返回来的永远是一个列表。

  2. 获取某个标签的属性值:

    href = html.xpath("//a/@href")
    # 获取a标签的href属性对应的值
    
  3. 获取文本,是通过xpath中的text()函数。示例代码如下:

    address = tr.xpath("./td[4]/text()")[0]
    
  4. 在某个标签下,再执行xpath函数,获取这个标签下的子孙元素,那么应该在斜杠之前加一个点,代表是在当前元素下获取。示例代码如下:

    address = tr.xpath("./td[4]/text()")[0] 
    img_url=div.xpath('.//img/@src')
    
  5. 父节点 ..

    result=html.xpath('//a[@href='link1.html']/../@class')
    #先获取href属性为link1.html的a节点,然后获取其父节点,最后获取其class属性值
    
  6. 属性匹配----使用@进行属性过滤

    .xpath('//li[@class="item-0"]') 
    #获取所有class="item-0"的li标签,返回列表
    
  7. 属性的-多值匹配

    .xpath('//li[contains(@class),"属性值"]')
    #contains()方法,第一个参数传入属性名称,第二个参数传入属性值
    
  8. 多属性 -匹配

    .xpath('//li[contains(@class),"属性值"  and @name="属性值"]')
    .xpath('//li[@class="属性值"  and @name="属性值"]')
    and or < ><= >= 等等
    
    
posted @ 2020-02-21 20:39  Noob52037  阅读(229)  评论(0编辑  收藏  举报