Python爬虫学习:DOM操作器XPATH

本文深入解析了DOM(文档对象模型)及其在W3C标准下的三个组成部分:核心DOM、XMLDOM和HTMLDOM,并通过实例展示了如何使用XPath进行HTML和XML文档的节点查询,包括路径、属性、逻辑运算等高级用法。

1.DOM

DOM 是 W3C(万维网联盟)的标准,DOM 定义了访问 HTML 和 XML 文档的标准,DOM 是 Document Object Model(文档对象模型)的缩写。
W3C DOM 标准被分为 3 个不同的部分:

核心 DOMXML DOMHTML DOM
针对任何结构化文档的标准模型针对 XML 文档的标准模型针对 HTML 文档的标准模型

HTML DOM树
HTML DOM树

2.XPath

在介绍XPath之前,要先确保lxml已经安装成功,若出现问题,可参考
lxml安装详细记录
XPath,全称XML Path Language,即路径语言,它是一门XML文档中查找信息的语言。做爬虫时,完全可以用XPath来做相应的信息抽取。

  1. 常用规则
表达式描述
nodename选取此节点的所有子节点
/从根节点选取,选择直接子节点,不包含更小的后代(例如孙、从孙)
//从当前路径选择文档中的节点,而不考虑它们的位置,包含所有后代
.选取当前节点
. .选取当前节点的父节点
@选取属性

nodename:指定节点的节点名称。

# 测试代码test.html
<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <div class='main-content'>
            <h1 id="title">This is a test!</h1>
            <p class="main-content ref">This is paragraph1</p>
            <div>
                <p>测试语句1</p>
            </div>
        </div>
        <div>
            <p>This is paragraph2</p>
            <div>
                <p class="ref">测试语句2</p>
            </div>
        </div>
    </body>
</html>
#实例
from lxml import etree	#首先导入lxml库的etree模块
import re
with open('test.html','r') as f:
    c = f.read()
s =re.sub('\n','',c)	#将所有的空格替换掉
tree = etree.HTML(s)
#测试‘/’的用法
test1 = tree.xpath('/html/body/div/p')
print(len(test1))
#测试‘//’的用法
test2 = tree.xpath('/html/body/div//p')
print(len(test2))
print(test1[1].text)
print(test2[3].text)

此时若只想得到第一个div下的p

from lxml import etree	#首先导入lxml库的etree模块
import re
with open('test.html','r') as f:
    c = f.read()
s =re.sub('\n','',c)	#将所有的空格替换掉
tree = etree.HTML(s)
#在XPath里数组下标从1开始,切记!!!
test1 = tree.xpath('/html/body/div[1]/p')
#如果想得到第一个div下的所有节点
test2 = tree.xpath('/html/body/div[1]//*')
print(len(test1))	#返回结果:	1
print(test1[0].text)	#返回结果:This is paragraph1

调用div节点下节点的另一种表达方法

from lxml import etree	#首先导入lxml库的etree模块
import re
with open('test.html','r') as f:
    c = f.read()
s =re.sub('\n','',c)	#将所有的空格替换掉
tree = etree.HTML(s)
#得到第一个div下的p节点
test1 = tree.xpath('/html/body/div')[0].xpath('p')
print(len(test1))	#结果返回值:1
#此种形式下,不能通过以下方式调用重孙节点,返回值错误,返回的是所有节点P
#test1 = tree.xpath('/html/body/div')[0].xpath('//p')

在DOM树,以路径的方式查询节点,通过@符号来选取属性

from lxml import etree
import re
with open('test.html','r',encoding='UTF-8') as f:
    c = f.read()
s =re.sub('\n','',c)
tree = etree.HTML(s)
#通过加入[@id="title"]限制节点id为'title'
test = tree.xpath('//*[@id="title"]')	#返回结果是一个列表
test1 = tree.xpath('//*[@id="title"]')[0]
print(test)	#返回结果:[<Element h1 at 0x25d0558>]
print(test1.attrib['id'])	#返回结果:title
print(test1.text)	#返回结果:This is a test!
  1. = 符号要求属性完全匹配,可以用 contains 方法来部分匹配
from lxml import etree
import re
with open('test.html','r',encoding='UTF-8') as f:
    c = f.read()
s =re.sub('\n','',c)
tree = etree.HTML(s)
# "="符号表示完全匹配
test1 = tree.xpath('//p[@class="ref"]')	#返回结果:[<Element p at 0x2360530>]
#contains方法可以实现部分匹配,只要class属性"ref"就会被匹配
test = tree.xpath('//p[contains(@class,"ref")]') #返回结果:[<Element p at 0x2360558>, <Element p at 0x2360530>]
print(test[0].attrib)	#{'class': 'main-content ref'}
print(test[1].attrib)	#{'class': 'ref'}
print(test[0].text)	#This is paragraph1
print(test[1].text)	#测试语句2
  1. 属性选择之逻辑运算
from lxml import etree
import re
with open('test.html','r',encoding='UTF-8') as f:
    c = f.read()
s =re.sub('\n','',c)
tree = etree.HTML(s)
# 在所有标签中选取所有的p标签或h1标签的元素
test = tree.xpath('//p | //h1')
#与上式含义相同:test = tree.xpath('//*[self::p or self::h1]')
print(len(test))		#返回结果:5
print(test)
#返回结果:[<Element h1 at 0x820580>, <Element p at 0x820558>, <Element p at 0x820530>, <Element p at 0x8200f8>, <Element p at 0x81edf0>]
# 结果一定是按顺序输出的
for i in test:
    print(i.text)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南淮北安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值