爬虫学习笔记第4章.解析库的使用.1 使用XPath

XPath:全称XML Path Language(XML路径语言),一门用于XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行导航。XPath同样可以用于HTML的搜索。

XPath 路径表达式:XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。

1 - 初始化:模块导入与对象构建

  1. 模块导入。
    Python中需要导入lxml库中的etree模块来使用XPath,即Python中需要导入lxml库中的etree模块来使用XPath,
from lxml import etree
  1. 解析对象构建。
    用两种方式用于构建XPath解析对象。

若text变量是html文本字符串,则可使用

html=etree.HTML(text)

若文件test.html是html文本文件,则可使用

html=etree.parse('test.html',etree.HTMLParser())

需要注意的是,这里etree模块自动修正了html文本。

2 - XPath节点

XML文档或者HTML文档是被当做节点树来对待的。
XPath中有七种属性的节点:元素节点,属性节点,文本节点,命名空间节点,处理指令节点,注释节点以及文档(根)节点。常用的是前三种。
以下是常用术语:

  1. 基本值/原子值(Atomic Value):无父或无子的节点。
  2. 项目(Item):基本值或节点。
  3. 父(Parent):每个元素或属性的直接上级节点。
  4. 子(Children):每个元素的下级节点。数量可能是0,1或者多个。
  5. 同胞(Sibling):拥有相同父的节点。
  6. 祖先(Ancestor):某个节点的父,父的父,等等。
  7. 后代(Descendant):某个节点的子,子的子,等等。

4 - XPath选取

XPath的选取非常简单,若html是XPath解析对象,path是路径表达式字符串(将会在以下讲解),则使用方法是

result=html.xpath(path)

返回选取结果result将是一个列表。再次选取可使用Python列表方法。
如果选取到的是元素,其形式将是类似<Element li at 0x10a3992c8>;
如果是其他,每个列表元素将是一个字符串。

3 - 常用路径表达式

表达式 描述 例子 效果
nodename 选取此节点所有子节点 book 选取book节点的所有子节点
/ 从当前节点选取直接子节点 /li 当前节点的名叫li的子节点
// 从当前节点选取所有子孙节点 //a 当前节点所有名叫a的子节点
选取当前节点的父节点 li//… 当前li节点的父节点
@ 选取属性 @class class属性
* 通配符:可匹配任意节点 //* 选取所有节点

以下是用于示例的html文本:

<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-2"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
<li class="item-1 it" name=“sixth”><a href="link6.html">sixth item</a></li>
<li class="item-1 it" name=“seventh”><a href="link7.html">seventh item</a></li>
</ul>
</div>

以下是选取示例:

  • ‘//*’:所有节点(从文件根节点下选取所有节点)
  • ‘//li/a’:所有li节点的所有直接a子节点
  • ‘//ul//a’:所有ul节点下的所有a子孙节点
  • ‘//li[@class=“item-1”]’:属性匹配。所有class属性为item-1的li节点(即第二个li节点,注意没有第6个)。
  • ‘//a[@href=“link4.html”]/…/@class’:选取href属性为link4.html的a节点后,选取其直接父节点(即第4个li节点),再选取其属性(‘item-1’)
  • ‘//li[@class=“item-0”]/a/text()’:文本获取。所有class属性为item-0的li节点(第一个和第五个)的直接a节点的所有文本( [‘first item’,‘fifth item’] )
  • ‘/li[@class=“item-0”]//text()’:所有class属性为item-0的li节点及其子孙节点的所有文本。
  • ‘//li[@class=“item-inactive”]/a/@href’:属性获取。所有class属性为item-inactive的li节点下a节点的href属性([‘link3.html’])。
  • ‘//li[contains(@class,“it”)]/a/text()’:属性多值匹配。所有class属性包含it的li节点(第6个)下直接a节点的文本。
  • ‘//li[contains(@class,“it”) and @name=“seventh”]/a/text()’:多属性匹配。所有class属性包含it且name属性包含seventh的li节点(即第7个)下的a节点的文本。

4 - 按序选择与节点轴选择

示例为以下html文本。

<div>
<ul>
<li class="item-0"><a href="link1.html"><span>first item<span></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-2"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
<li class="item-1 it" name=“sixth”><a href="link6.html">sixth item</a></li>
<li class="item-1 it" name=“seventh”><a href="link7.html">seventh item</a></li>
</ul>
</div>
  • ‘//li[2]/a/text()’:第2个(注意与数组不同)li节点的子节点a下的文本([‘second item’])
  • ‘//li[last()]’:last()函数。最后一个li节点(即第7个)。
  • ‘//li[last()-2]’:倒数第3个li节点(最后一个倒推2个)。
  • //li[position()<4]’:position()函数。位置小于3(即第一个,第二个和第三个)的li节点。
  • ‘//li[1]/ancestor:: *’:节点轴选择之ancestor轴。选取第一li节点的所有祖先节点(将包括文件根节点html节点,body节点,以及明面上的ul和div节点)。
  • ‘//li[1]/ancestor::div’:选取第一个li节点的div祖先节点。
  • ‘//li[7]/attribute:: *’:选取第7个li节点的所有属性值([‘item-1’,‘it’])。
  • ‘//li[3]/child::a[@href=“link3.html”]’:第3个li节点的所有子节点中href属性为link3.html的a节点。
  • ‘li[1]/descendant:: span’:第一个li节点的所有子孙节点中的span节点。
  • ‘li[5]/following:: *[2]’:第5个li节点的所有文本中后续节点(包括一切子孙节点)中的第二个。
  • ‘li[2]/following-sibling:: *’ :第2个li节点的所有后续同胞节点。

5 - 一些其他

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

猜你喜欢

转载自blog.csdn.net/u013942370/article/details/82916982