Day 11 11.1 Xpath解析
xpath解析
xpath在Python的爬虫学习中,起着举足轻重的地位,对比正则表达式 re两者可以完成同样的工作,实现的功能也差不多,但xpath明显比re具有优势,在网页分析上使re退居二线。
xpath 全称为XML Path Language 一种小型的查询语言
xpath的优点:
- 可在XML中查找信息
- 支持HTML的查找
- 通过元素和属性进行导航
python开发使用XPath条件: 由于XPath属于lxml库模块,所以首先要安装库lxml。
from lxml import etree
selector=etree.HTML(源码) #将源码转化为能被XPath匹配的格式
selector.xpath(表达式) #返回为一列表
【1】路径表达式
| 表达式 | 描述 | 实例 | 解析 |
|---|---|---|---|
| / | 从根节点选取 | /body/div[1] |
选取根结点下的body下的第一个div标签 |
| // | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 | //a |
选取文档中所有的a标签 |
| ./ | 当前节点再次进行xpath | ./a |
选取当前节点下的所有a标签 |
| @ | 选取属性 | //@calss |
选取所有的class属性 |
from lxml import etree
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
selector = etree.HTML(html_doc)
print(type(selector)) #<class 'lxml.etree._Element'>
results = selector.xpath("//a")
print(results) # [<Element a at 0x2155de71640>, <Element a at 0x2155e3976c0>, <Element a at 0x2155e397800>]
for result in results:
href = result.xpath('./@href')
href1 = result.xpath('./@href')[0] #获取标签里的href值
href2 = result.xpath('./text()')[0] #获取标签里的文本值
print(href)#['http://example.com/elsie'] ['http://example.com/lacie'] ['http://example.com/tillie']
print(href1)#http://example.com/elsie http://example.com/lacie http://example.com/tillie
print(href2) #Elsie Lacie Tillie
【2】谓语(Predicates)
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
| 路径表达式 | 结果 |
|---|---|
| /ul/li[1] | 选取属于 ul子元素的第一个 li元素。 |
| /ul/li[last()] | 选取属于 ul子元素的最后一个 li元素。 |
| /ul/li[last()-1] | 选取属于 ul子元素的倒数第二个 li元素。 |
| //ul/li[position()️] | 选取最前面的两个属于 ul元素的子元素的 li元素。 |
| //a[@title] | 选取所有拥有名为 title的属性的 a元素。 |
| //a[@title='xx'] | 选取所有 a元素,且这些元素拥有值为 xx的 title属性。 |
//a[@title>10] > < >= <= != |
选取 a元素的所有 title元素,且其中的 title元素的值须大于 10。 |
| /body/div[@price>35.00] | 选取body下price元素值大于35的div节点 |
【3】选取未知节点
XPath 通配符可用来选取未知的 XML 元素。
| 通配符 | 描述 |
|---|---|
| * | 匹配任何元素节点。 |
| @* | 匹配任何属性节点。 |
| node() | 匹配任何类型的节点。 |
实例
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
| 路径表达式 | 结果 |
|---|---|
| /ul/* | 选取 bookstore 元素的所有子元素。 |
| //* | 选取文档中的所有元素。 |
| //title[@*] | 选取所有带有属性的 title 元素。 |
| //node() | 获取所有节点 |
【4】选取若干路径
通过在路径表达式中使用“|”运算符,您可以选取若干个路径。
实例
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
| 路径表达式 | 结果 |
|---|---|
| //book/title | //book/price | 选取 book 元素的所有 title 和 price 元素。 |
| //title | //price | 选取文档中的所有 title 和 price 元素。 |
| /bookstore/book/title | //price | 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。 |
- 逻辑运算
//div[@id="head" and @class="s_down"] # 查找所有id属性等于head并且class属性等于s_down的div标签
//title | //price # 选取文档中的所有 title 和 price 元素,“|”两边必须是完整的xpath路径
- 属性查询
//div[@id] # 找所有包含id属性的div节点
//div[@id="maincontent"] # 查找所有id属性等于maincontent的div标签
//@class
//li[@name="xx"]//text() # 获取li标签name为xx的里面的文本内容
- 获取第几个标签 索引从1开始
tree.xpath('//li[1]/a/text()') # 获取第一个
tree.xpath('//li[last()]/a/text()') # 获取最后一个
tree.xpath('//li[last()-1]/a/text()') # 获取倒数第二个
- 模糊查询
//div[contains(@id, "he")] # 查询所有id属性中包含he的div标签
//div[starts-with(@id, "he")] # 查询所有id属性中包以he开头的div标签
//div/h1/text() # 查找所有div标签下的直接子节点h1的内容
//div/a/@href # 获取a里面的href属性值
//* #获取所有
//*[@class="xx"] #获取所有class为xx的标签
# 获取节点内容转换成字符串
c = tree.xpath('//li/a')[0]
result=etree.tostring(c, encoding='utf-8')
print(result.decode('UTF-8'))
【5】案例
豆瓣Top250基于xpath解析:
import requests
from lxml import etree
url = "https://movie.douban.com/top250?start=0"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36"
}
resp = requests.get(url, headers=headers)
tree = etree.HTML(resp.text) # 加载页面源代码
items = tree.xpath('//li/div[@class="item"]/div[@class="info"]')
for item in items:
title = item.xpath('./div[@class="hd"]/a/span[1]/text()')[0]
rating_num = item.xpath('./div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()')[0]
comment_num = item.xpath('./div[@class="bd"]/div[@class="star"]/span[4]/text()')[0]
print(title, rating_num, comment_num)
练习:基于xpath完成解析练习
import requests
from lxml import etree
res = requests.get("https://top.baidu.com/board?platform=pc&sa=pcindex_entry", )
selector = etree.HTML(res.text)
rets = selector.xpath('//div[@theme="car"]//div[contains(@class,"item-wrap_Z0BrP ")]')
info = {}
for i in rets:
name = i.xpath('./div[@class="normal_1glFU"]/a/text()')
link = i.xpath('./div[@class="normal_1glFU"]/a/@href')
info[name[0]] = link[0]
print(info)
print(len(info))
Day 11 11.1 Xpath解析的更多相关文章
- JAVA通过XPath解析XML性能比较
转自[http://www.cnblogs.com/mouse-coder/p/3451243.html] 最近在做一个小项目,使用到XML文件解析技术,通过对该技术的了解和使用,总结了以下内容. 1 ...
- BeautifulSoup与Xpath解析库总结
一.BeautifulSoup解析库 1.快速开始 html_doc = """ <html><head><title>The Dor ...
- Xpath解析库的使用
### Xpath常用规则 ## nodename 选取此节点的所有子节点 ## / 从当前节点选取直接子节点 ## // 从当前节点选取子孙节点 ## . 选取当前节点 ## .. 选取当前节点的父 ...
- NOIp 11.11/12
最后一场比较正式的NOIp模拟赛,写一发小总结.题目没什么好说的,大部分很简单,先贴一下代码. 1111 T1 //string //by Cydiater //2016.11.11 #include ...
- 11.11光棍节工作心得——github/MVP
11.11光棍节工作心得 1.根据scrum meeting thirdday中前辈的指导进行学习 我在博客中贴了链接,竟然TrackBack引来了原博主,
- JAVA通过XPath解析XML性能比较(原创)
(转载请标明原文地址) 最近在做一个小项目,使用到XML文件解析技术,通过对该技术的了解和使用,总结了以下内容. 1 XML文件解析的4种方法 通常解析XML文件有四种经典的方法.基本的解析方式有两种 ...
- 利用XPath解析带有xmlns的XML文件
在.net中,编写读取xml 的程序中提示"未将对象引用设置到对象的实例",当时一看觉得有点奇怪.为什么在读取xml数据的时候也要实例化一个对象.google了才知道,xml文件中 ...
- 爬虫系列二(数据清洗--->xpath解析数据)
一 xpath介绍 XPath 是一门在 XML 文档中查找信息的语言.XPath 用于在 XML 文档中通过元素和属性进行导航. XPath 使用路径表达式在 XML 文档中进行导航 XPath 包 ...
- python开发遇到的坑(1)xpath解析ValueError: Unicode strings with encoding declaration are not supported
Traceback (most recent call last): File "/Users/*******.py", line 37, in <module> Bt ...
- xpath解析数据
xpath解析数据 """ xpath 也是一种用于解析xml文档数据的方式 xml path w3c xpath搜索用法 在 XPath 中,有七种类型的节点:元素.属 ...
随机推荐
- 02_IntelliJ IDEA常用快捷键
[常见快捷键] Ctrl+Shift + Enter 语句完成 "!" 否定完成 输入表达式时按 "!"键 Ctrl+E 最近的文件 Ctrl+Shif ...
- Intel与AMD之间的故事
本人中文作文水平仅仅达到小学一年级,通俗易懂,不会术语,对于外行人特别友好,内行人不吝赐教,多谢指正! 背景:Intel(CPU制造商大哥),AMD(二哥,yes) 诺伊斯(Intel创始人,集成电路 ...
- 创建一个spring项目
- vue 传参跳转 iview、element组件
方法一1.本页vue跳转链接. <router-link :to="{path:'/details_page',query: {type:items.types,id: items.i ...
- allure+testng遇到的一些问题
java+testng+allure 听说allure报告,"很好看",决定引入. 首先看allure官网,需要在pom.xml中引入包 文档:https://docs.qamet ...
- ps如何正确擦除文字 如何正确用ps擦除文字
1.启动PS:新建文档,进入到软件操作界面中. 2.再把图片素材拖入到PS中.接下来,要把图片上的文字清除掉. 3.按L键,调出套索工具,接着,把文字给框选出来. 4.再按SHIFT+F5调出填充对话 ...
- SpringBoot Circular view path错误
在运行SpringBoot时报了这样一个错误 百度翻译是视图循环 搜索一下 原来是类上restcontroller写成了controller 对比一下两者 @Controller和@RestCont ...
- ESXI虚拟机 硬盘扩容/目录(添加新硬盘)
背景: 线上服务器,磁盘Linux的虚拟机根分区已经使用90%,触发了磁盘告警,再一顿操作删除后,勉勉强强回到了82%,现在需要对根目录进行扩容. 进入到EXSI管理平台,看到原来的sda磁盘只有30 ...
- CCPC2021 广州 K. Magus Night
CCPC2021 广州 K. Magus Night 题意 给定整数区间 \([1,m]\) ,从中可重复的选择 \(n\) 个数,形成一个数列 \(\{a_n\}\) .问:所有满足 \(\gcd( ...
- SQL server数据库 账户SA登录失败,提示错误:18456
在我们使用数据库的时候,偶尔会遇到一些登录上的错误提示.比如,在数据库配置上没有正确开启用户的登录策略以及服务器身份验证模式时,就会提示"用户'sa'登录失败.(Microsoft SQL ...