其他
强大的Xpath:你不能不知道的爬虫数据解析库
公众号:尤而小屋
作者:Peter
编辑:Peter
Xpath介绍
XPath (XML Path)
是一门在 XML 文档中查找信息的语言。XPath
可用来在XML
文档中对元素和属性进行遍历。Xpath是一种查询语言 在XML(Extensible Markup Language)和HTML的树状结构中寻找节点 XPATH是一种根据‘地址’来‘寻找人’的语言
Xpath安装
import lxml
没有报错,即表示安装成功!Xpath解析原理
实例化一个etree解析对象,且需要将解析的页面源码数据加载到对象中 调用xpath中的xpath解析方法结合着xpath表达式实现标签的定位和内容的捕获
将本地的html文档中的源码数据加载到etree对象中:etree.parse(filePath) 将互联网上获取的源码数据加载到该对象中:etree.HTML('page_text'),其中page_text指的就是我们获取到的源码内容
Xpath使用方法
3个特殊符号
/:表示从根节点开始解析,并且是单个层级,逐步定位 //:表示多个层级,可以跳过其中的部分层级;也表示从任意位置开始定位 .:一个点表示当前的节点
常见路径表达式
举例
Xpath运算符
HTML元素
HTML 元素以开始标签起始;HTML 元素以结束标签终止 元素的内容是开始标签与结束标签之间的内容 某些 HTML 元素具有空内容(empty content) 空元素在开始标签中进行关闭(以开始标签的结束而结束) 大多数 HTML 元素可拥有属性;属性推荐使用小写
<br />
,是关闭空元素的正确方法,HTML、XHTML 和 XML 都接受这种方式。常见属性
HTML标题
<h1> - <h6>
等标签进行定义的。<h1>
定义最大的标题,<h6>
定义最小的标题。原数据
from lxml import etree
# 实例化解析对象
tree = etree.parse("test.html")
tree
<head>
<meta charset="utf-8" />
<title>古代诗人及作品</title>
</head>
<body>
<div>
<p>诗人姓名</p>
</div>
<div class="name">
<p>李白</p>
<p>白居易</p>
<p>李清照</p>
<p>杜甫</p>
<p>王安石</p>
<a href="http://wwww.tang.com" target="_self" title="李世民">
<span> this is span </span>
古代诗人写的诗词真的非常棒</a>
<a class="du" href="">床前明月光,疑是地上霜</a>
<img alt="" src="http://www.baidu.com/tang.jpg" />
</div>
<div class="tang">
<ul>
<li><a href="http://www.baidu.com" title="百度">朝辞白帝彩云间,千里江陵一日还</a></li>
<li><a href="http://www.sougou.com" title="搜狗">清明时节雨纷纷,路上行人欲断魂</a></li>
<li><a alt="360" href="http://www.360.com">秦时明月汉时关,万里长征人未还</a></li>
<li><a href="http://www.sina.com" title="必应">君子赠人以言,庶人赠人以财</a></li>
<li><b>苏轼</b></li>
<li><i>苏洵</i></li>
<li><a href="http://www.google.cn" id="谷歌">欢迎使用谷歌浏览器</a></li>
</ul>
</div>
</body>
</html>
获取单个标签内容
title
title = tree.xpath("/html/head/title/text()")[0] # 索引0表示取得第一个元素值
title
获取标签内的多个内容
属性定位
[@属性名="属性值"]
:name
索引定位
Xpath中索引是从1开始,和python中的索引从0开始是不同的。
比如想定位div标签下class属性(值为name)下的全部p标签:5对p标签,结果应该是5个元素
index = tree.xpath('//div[@class="name"]/p')
index
index = tree.xpath('//div[@class="name"]/p[3]') # 索引从1开始
index
获取文本内容
第一种方法:text()方法
1、获取具体某个标签下面的元素:
class_text = tree.xpath('//div[@class="tang"]/ul/li/b/text()')
class_text
class_text = tree.xpath('//div[@class="tang"]//b/text()')
class_text
p_text = tree.xpath('//div[@class="name"]/p/text()')
p_text
p_text = tree.xpath('//div[@class="name"]/p[3]/text()')
p_text
|
abi_text = tree.xpath('//div[@class="tang"]//li/a/text() | //div[@class="tang"]//li/b/text() | //div[@class="tang"]//li/i/text()')
abi_text
直系和非直系理解
直系:表示获取标签下第一层级的文本内容 非直系:表示获取标签下面所有层级的文本内容
取属性内容
实战
本名熊耀华,江西人;台湾淡江英专(即淡江大学前身)毕业(一说肄业)。少年时期便嗜读古今武侠小说及西洋文学作品,一般多以为他是受到吉川英治、大小仲马、海明威、杰克伦敦、史坦贝克小说乃至尼采、沙特等西洋哲学的影响启迪。(古龙自己也说过“我喜欢从近代日本及西洋小说‘偷招’。”) 故能日新又新,後来居上,且别开武侠小说新境界。
网页分析
获取网页源码
from lxml import etree
import pandas as pd
url = 'https://www.kanunu8.com/zj/10867.html'
headers = {'user-agent': '请求头'}
response = requests.get(url = url,headers = headers)
result = response.content.decode('gbk') # 该网页需要通过gbk编码来解析数据
result
获取信息
href_list = tree.xpath('//tbody/tr//a/@href') # 指定属性的信息
href_list[:5]
name_list[:5]
gulong = pd.DataFrame({
"name":name_list,
"url":href_list
})
gulong
gulong
# 导出为excel文件
gulong.to_excel("gulong.xlsx",index=False)
总结
//:表示获取标签非直系内容,有跨越层级 /:表示只获取标签的直系内容,不跨越层级 如果索引是在Xpath表达式中,索引从1开始;如果从Xpath表达式中获取到列表数据后,再使用python索引取数,索引从0开始
一切看似逝去的,都不曾离开,你所给与的爱与温暖,让我执着地守护着这里