爬虫04_数据解析之xpath

环境安装:

基于xpath的数据解析主要使用lxml库中的etree

# pip install lxml

代码中引入类

from lxml import etree

解析原理:

  • 实例化一个etree类型的对象,然后将待解析的页面源码数据加载到此对象中
  • 调用etree对象的xpath方法,然后结合不同的xpath表达式,来实现网页中局部位置的标签定位和数据提取 (这里主要是提取文本文件和标签属性值)

测试页面:

测试页面代码数据

<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>测试xpath和bs4</title>
</head>
<body>
	<div>
		<p>百里守约</p>
	</div>
	<div class="song">
		<p>李清照</p>
		<p>王安石</p>
		<p>苏轼</p>
		<p>柳宗元</p>
		<a href="http://www.song.com/" title="赵匡胤" target="_self">
			<span>this is span</span>
		宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a>
		<a href="" class="du">总为浮云能蔽日,长安不见使人愁</a>
		<img src="http://www.baidu.com/meinv.jpg" alt="" />
	</div>
	<div class="tang">
		<ul>
			<li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li>
			<li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li>
			<li><a href="http://www.126.com" alt="qi">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li>
			<li><a href="http://www.sina.com" class="du">杜甫</a></li>
			<li><a href="http://www.dudu.com" class="du">杜牧</a></li>
			<li><b>杜小月</b></li>
			<li><i>度蜜月</i></li>
			<li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li>
		</ul>
	</div>
</body>
</html>

具体操作:

1. 实例化etree对象

  • etree.parse('filename'):表示将本地文件加载到该对象中
  • etree.HTML(page_text):表示将网站获取的页面数据加载到该对象中
from lxml import etree
tree = etree.parse('mytest.html') #test.html是保存在本地的测试网页
tree #打印出的tree = <lxml.etree._ElementTree at 0x106bbla88>
tree.xpath('xpath表达式') #返回的是一个列表

2. 实现标签定位

  • 基于xpath方式定位标签的原理:HTML标签可以看成以自上而下以树状图形式进行展示的文件,xpath因此可以较低的时间复杂度逐层帮我们快速定位需要的标签,计算机中的目录结构其实也是一个树状结构xpath的写法实际上和计算机的子目录路径差不多,例如/html/head/meta/user/Desktop/test
    在这里插入图片描述
  • 使用.xpath(‘xpath定位标签的表达式’)方法,然后以列表形式返回定位到的数据
  • 定位标签时xpath表达式的语法
    • 1)最左侧的/:如果xpath表达式最左侧是以/开头的,则表示该xpath表达式一定要从根标签节点开始定位指定标签,类似于绝对路径,但是通常不用最左侧斜杠 (可以忽略不记,了解即可)
    • 2)非最左侧的/:表示一个层级
    • 3)非最左侧的//:表示多个层级
    • 4)最左侧的//:表示我们的xpath表达式可以从任意的层级开始定位寻找,类似于相对路径,所有符合的标签都找到
    • 5)属性定位:tagName[@attrName="value"]就可以定位到我们指定的属性标签,例如[@class="song"]
    • 6)索引定位:tag[index]xpath表达式的索引是从1开始,不是从0开始
    • 7)模糊匹配://div[contains(@class, "ng")]//div[starts-with(@class, "ta")]
      注意:平时我们只需要使用属性定位索引定位就可定位到任意的局部标签
tree.xpath('/html/head/meta') #帮我们从树的根节点一层一层的遍历找到meta,返回的是[<Elements meta at 0x106c9ae48>]
tree.xpath('/html//meta') #定位meta方式2,非最左侧为'//',表示中间多个层级

#最左侧为"//"
tree.xpath('//meta') #定位meta方式3,最左侧为'//',表示相对位置
tree.xpath('//div') #表示在我当前文档中,给我找到所有的div标签

#属性定位:定位到class为song的div下面所有的p标签
tree.xpath('//div[@class="song"]/p')

#索引定位:定位到class为song的div下面的第二个p标签
tree.xpath('//div[@class="song"]/p[2]')

3. 题取内容(文本内容和属性值)

  • 提取文本内容
    • /text():表示提取出直系的文本内容,返回是一个列表
    • //text():表示提取出所有的文本内容,返回是一个列表
  • 提取属性
    • /@attrName:表示提取属性值,例如/@href,返回是一个列表
#提取song的第二个p标签下面的直系文本内容
tree.xpath('//div[@class="song"]/p[2]/text()')
#提取song的第二个p标签下面的所有文本内容
tree.xpath('//div[@class="song"]/p[2]//text()')

#提取id为"feng"所对应的a标签里的href属性的值和内容
tree.xpath('//a[@id="feng"]/@href')

实例项目练习

  • 使用xpath爬取前5页所有的图片名称和图片数据:练习网站网址
  • 项目代码展示:
import requests
from lxml import etree

headers = {'User-Agent':''}

总结:

  • 在xpath表达式中,不能出现tbody标签,否则会导致xpath解析失效,参考爬取西刺代理案例
发布了38 篇原创文章 · 获赞 43 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_40272386/article/details/105415266