Python 爬虫之 xpath

0x01 XML 基础

xpath 是在 XML 文档中搜索内容的一门语言

HTML 是 XML 的一个子集

XML 代码举例:

<book>
    <isbn>978xxxxxxxx</isbn>
    <name>XML从入门到精通</name>
</book>

其中:

  1. <book><isbn>等称为节点

    1. <book><isbn>的父节点
    2. <isbn><book>的子节点之一
    3. <isbn><name>互为兄弟节点
  2. 通过节点之间的关系,从根节点查找任意节点,如\book\isbn

    xpath 查找原理

0x02 解析 XML

安装 lxml 模块:pip install lxml(4.5.0)

lxml 用法步骤:

  1. 将需要解析的 HTML 内容构造出 etree 对象

  2. 使用 etree 对象的xpath()方法配合 xpath 表达式来完成对数据的提取

    from lxml import etree
    
    html = """
    <book>
        <isbn>978xxxxxxxx</isbn>
        <name>XML从入门到精通</name>
            <ctx id="111">内容一</ctx>
            <ctx id="222">内容二</ctx>
            <div>
                <ctx id="333">内容三</ctx>
            </div>
    </book>
    """
    et = etree.XML(html)
    
    
    # 根据节点进行搜索
    res1 = et.xpath("/book")
    res2 = et.xpath("/book/isbn")
    res3 = et.xpath("/book//ctx")
    res4 = et.xpath("/book/*/ctx")
    res5 = et.xpath("/book//ctx/text()")    # 获取该节点的文本
    # 输出结果
    print(res1)
    print(res2)
    print(res3)
    print(res4)
    print(res5)
    

0x03 解析 HTML

测试用 HTML:

<html>
    <head>
        <meta charset="utf-8" >
        <title>页面标题</title>
    </head>
    <body>
        <h1>标题一</h1>
        <h2>标题二</h2>
        <h3>标题一</h3>
        <h4>标题一</h4>
        <a href="http://www.qq.com">腾讯网</a>
        <div id="content" class="default">
            <p>段落</p>
            <a href="http://www.baidu.com">百度</a>
            <a href="http://www.cnblogs.com/SRIGT">我的博客</a>
            <a href="test">测试</a>
            <img src="./logo.ico" />
        </div>
    </body>
</html>

python 代码:

当标签使用不规范时,使用 xpath 爬取会报错

如:

<!-- 不规范 -->
<meta charset="utf-8">
<!-- 规范 -->
<meta charset="utf-8" />
from lxml import etree

et = etree.parse("test.html")
res1 = et.xpath('/html')
res2 = et.xpath("/html/body//a/text()")                     # 所有<a>标签的文本
res3 = et.xpath("/html/body/div/a[1]/text()")               # 第1个<a>标签的文本
res4 = et.xpath("/html/body/div/a[@href='test']/text()")    # 由属性值索引的文本
print(res4)
print()

links = et.xpath("/html/body/div/a")
for link in links:
    res5_1 = link.xpath("./text()")
    print(res5_1)
    res5_2 = link.xpath("./@href")
    print(res5_2)

res6 = et.xpath("/html/body/div/a/@href")
print(res6)

End

posted @ 2023-03-10 09:37  SRIGT  阅读(38)  评论(0编辑  收藏  举报