Python爬虫——用XPath解析网页源码

首先先来介绍下XPath是什么东西:
XPath是一个用路径表达式来提取XML文档中节点的工具,我们有很多像有界面的东西都是用xml语言写的,其中HTML就是xml的一种;下面举个栗子理解一下:

<html>
    <body>
	<h1>title</h1>
	<p>paragraph</p>
	<div id="img-13012085" class="box">
            <h1>title2</h1>
	    <a title="bizhi..." href="/p/13012085.html" >
		<img alt="bizhi..."  src="https://img11.51tietu.net/pic/2019112816/dgmgjm04q53dgmgjm04q53280x180.jpg" >
	    </a>
	</div>
	<div id="img-13012083" class="box">
            <h1>title3</h1>
	    <a title="bizhi..." href="/p/13012083.html" >
		<img alt="bizhi..."  src="https://img11.51tietu.net/pic/2019112816/yxjxlzj0atayxjxlzj0ata280x180.jpg" >
	    </a>
	</div>
    </body>
</html>

什么是路径,比如我们要从上面找到 “title” 这个文字,我们要怎么找:html -> body -> h1,我们需要的文字就在<h1></h1>标签之间,我们只需要把h1标签找到,再把里面的内容提取出来就好了,那么像html、body这些标签就是我们的节点;XPath就是一种通过节点一层一层找到内容的文本提取工具;下面我们就通过代码把上面的那段文字提取出来:

from lxml import etree    # 如果没有安装的话,用 pip install lxml 安装
                          # 我们需要把etree库导入

with open('test.html','r') as f:    # 打开我们的html文件,内容就是上面的内容
    read = f.read()                 # 将文件的内容读取出来
html = etree.HTML(read)    # 返回lxml.etree._Element对象
                           # 这一步还有补全代码的功能,如果代码有标签的闭合确实,他可以自动补全
str = html.xpath('/html/body/h1/text()')    # 通过xpath()方法进行匹配,后面的text()就是指文本值的意思
                                            # h1下面的文本就是'title'了

print(str)    # 最后我们让结果输出

# 输出结果:
# ['title']

上面我们使用的是绝对路径的方法,我们发现上面的代码中有三个<h1>,如果我想搜索所有的<h1>标签,那需要怎么处理呢?

from lxml import etree

with open('test.html','r') as f:
    read = f.read()
html = etree.HTML(read)
str = html.xpath('//h1/text()')    # //h1表示所有的h1节点,

print(str)

# 输出结果:
# ['title', 'title2', 'title3']

现在我需要获取第一张图片的所有信息,想要将红框框选的代码单独提取出来,然后再做处理,这该怎么做呢?

from lxml import etree

with open('test.html','r') as f:
    read = f.read()
html = etree.HTML(read)
data = html.xpath('//div[@id="img-13012085"]')   # []代表匹配里面的属性,@id表示属性的名字
                                                 # 注意://匹配,最后返回的是一个列表,我们要在最后指明是哪一个匹配项,
                                                 # 或者遍历列表的所有项
# data = html.xpath('//div[@id="img-13012085"]')[0]

for d in data:    # 遍历所有匹配项
    print(d.xpath('./h1/text()'))    # 将所有匹配项的h1标签内容输出

print(str)

# 输出结果:
# ['title2']

现在问题又来了,我需要将所有div便签内的h1内容输出,那么该怎么做:

from lxml import etree

with open('test.html','r') as f:
    read = f.read()
html = etree.HTML(read)
data = html.xpath('//div[contains(@id,"img-1301")]')    # contains是一种不完全匹配,就是说相应属性值包含字段即可

for d in data:
    print(d.xpath('./h1/text()'))

# 输出结果:
# ['title2']
# ['title3']

 

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值