Xpath

Xpath (XML Path Language)是在 XML 文档中选择节点的语言

一、XPath 路径表达式

1、XPath 节点

在 XPath 中,有七种类型的节点:元素属性文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的,树的根被称为文档节点或者根节点

2、XPath 节点关系

父(Parent)子(Children)同胞(Sibling)先辈(Ancestor)后代(Descendant)

3、选取节点

XPath 使用路径表达式在 html 文档中选取节点。

[A]/B:A 中所有的 B 子节点;A 缺省 B 指 html 节点,即:/ 为根节点。
对 html 的子节点可以通过节点名选取,如:head 选取所有的 html 下的子节点 head。
[A]//B:A 的所有后代节点 B,如: //div 文档中所有 div 节点,body//div: body 所有的的后代节点  div。
.	选取当前节点
..	选取当前节点的父节点	
*	匹配任何元素节点,如:div/* 选取 div 元素的所有子元素,//*	选取文档中的所有元素。
@ 选取属性,如://@lang	选取名为 lang 的所有属性。
@* 匹配任何属性节点,如://title[@*]	选取所有带有属性的 title 元素。

ul/li[1] : ul 子元素的第一个 li 元素。
ul/li[last()]	: ul 子元素的最后一个  li 元素。
ul/li[last()-1]: ul 子元素的倒数第二个 li 元素。
ul/li[position()<3]: ul 元素的前2个 li 元素。
//title[@lang]:所有拥有 lang 属性的 title 元素。
//title[@lang='en']:所有拥有 lang 属性值为 'en' 的 title 元素。
ul/li[price>35.00]:ul 元素的拥有 price>35.00 的 li 元素。
ul/li[price>35.00]//title:ul 元素的拥有 price>35.00 的 li 元素的 title 元素。

node()	匹配任何类型的节点
text() ,如:p/text() 选取节点中的所有文本。
"|" 运算符,如:div | p 选取所有的 div 节点和 p 节点,即返回所有拥有 div 和 p 元素的节点集。

4、XPath 轴

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

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

二、实例

from requests_html import HTML

doc = '''<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">  
    <title>Test Document</title>
</head>
<body>
    <div id='content'>
        <ul class='list'>
            <li class='one'>One</li>
            <li class='two'>Two</li>
            <li class='three'>Three</li>
            <li class='four four1 four2 four3'>Four</li>
            <div id='inner'>呵呵呵
                <a href='http://www.baidu.com'>百度一下</a>
                <p>第1段</p>
                <p>第2段</p>
                <p>第3段</p>
                <p>第4段<span id="first">python 程序设计</span> </p>
                <p>第5段</p>
                <p>第6段</p>
            </div>
            <div id='inne inner'>嘿嘿嘿</div>
        </ul>
        <ul class='text'>This is Text</ul>
    </div>
</body>
</html>'''

html = HTML(html=doc)
contents = html.xpath("//*[@id='inner']/p[4]/text()")
# 结果是一个列表
content = html.xpath("//*[@id='inner']/p[4]",first=True)
for i in contents:
    print(i)
    print('-'*20)

print(content.text)