当前位置: 首页 > news >正文

Xpath学习笔记

Xpath原理:先将HTML文档转为XML文档,再用xpath查找HTML节点或元素
什么是xml?
1、xml指可扩展标记语言
2、xml是一种标记原因,类似于html
3、xml的设计宗旨是传输数据,而非显示数据
4、xml标签需要我们自己自定义
5、xml被设计为具有自我描述性

xml和html的区别?
1、xml被设计为传输和存储数据,其焦点是数据的内容
2、html是显示数据以及如何更好的显示数据

# xml文档示例
# 这里面的标签都是自定义的
<?xml version="1.0" encoding="utf-8"?>
<bookstore><book category="cooking"><title lang="en">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book><book category="children"><title lang="en">Harry Potter</title><author>J K. Rowing</author><year>2005</year><price>29.99</price></book><book category="web"><title lang="en">XQuery Kick Start</title><author>James McGovern</author><author>Per Bothner</author><author>Kurt Cagle</author><author>James Linn</author><year>2005</year><price>49.99</price></book><book category="web" cover="paperback"><title lang="en">Learning XML</title><author>Erik T. Ray</author><year>2003</year><price>39.95</price></book></bookstore>

1、父(parent)
每个元素及属性都有一个父
下面xml例子中,book元是title,author,year,price元素的父

<?xml version="1.0" encoding="utf-8"?><book><title lang="en">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price>
</book>

2、子(children)
元素节点可能有零个,一个或者多个子
在下面的例子中title,author,year,price都是book元素的子

<?xml version="1.0" encoding="utf-8"?><book><title lang="en">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price>
</book>

3、同胞(sibling)
拥有相同的父的节点
在下面例子中title,author,year,price元素都是同胞

<?xml version="1.0" encoding="utf-8"?><book><title lang="en">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price>
</book>

4、先辈(ancestor)
某节点的父、父的父,等等
下面例子中,title元素的先辈是book和bookstore

<?xml version="1.0" encoding="utf-8"?><bookstore><book><title lang="en">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price>
</book></bookstore>

5、后代
某节点的子,子的子,等等
下面例子中,bookstore后代是book,title,author,year,price元素

<?xml version="1.0" encoding="utf-8"?><bookstore><book><title lang="en">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price>
</book></bookstore>

什么是xpath

xpath(xml path language)是一门在xml文档中查找信息的语言,可以用来在xml文档对元素和属性进行遍历

xml path language:xml路径语言

选取节点

xpath使用路径表达式来选取xml文档中的节点或者节点集,这些路径表达式和我们在常规表达式和我们在常规的电脑文件系统里看到的表达式非常相似

下面列出了最常用的路径表达式:
表达式 描述
nodename 选取此节点的所有子节点
/ 从根节点选取
// 从匹配选择的当前节点选择文档中的节点,而不考虑他们的位置
. 选取当前节点
… 选取当前节点的父节点
@ 选取属性
在下面表格中,我们列出了一些路径表达式以及表达式的结果:
bookstore 选取bookstore元素的所有子节点
/bookstore 选取根元素bookstore。注释:假如路径起始于正斜杠(/)则此路径始终代表到某元素的绝对路径
bookstore/book 选取属于bookstore的子元素的所有book元素
//book 选取所有book子元素,而不管他们在文档中的位置
bookstore//book 选取属于bookstore元素的后代的所有book元素,而不管他们位于bookstore之下的什么位置
…@lang 选取名为lang的所有属性

选取位置节点

xpath通配符可用来选取未知的xml元素
通配符 描述

  •           匹配任何元素的节点
    

@* 匹配任何属性的节点
node() 匹配任何类型的节点
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 结果
/bookstore/* 选取bookstore元素的所有子节点
//* 选取文档中的所有元素
html/node()/meta/@* 选取HTML下面任意节点下的meta节点的所有属性
//title[@*] 选取所有带有属性的title元素

选取若干路径

通过在路径表达式中使用“|”运算符,您可以选取若干个路径

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果
路径表达式 结果
//book/title|//book/price 选取book元素的所有title和price元素
//title|//price 选取文档中的所有title和price元素
/bookstore/book/title|//price 选取属于bookstore元素的book元素的所有title元素,以及文档中的所有price元素
这些就是xpath的语法内容妙哉运用到python抓取是要先转换为xml

lxml库

1、lxml库是一个HTML/xml的解析器,主要功能是如何解析和提取HTML/xml数据
2、lxml和正则一样,都是通过c语言实现的,他是一款高性能的python html/xml的解析器,我们可以利用之前所学习的xpath语法,来快速定位特定元素以及节点信息
3、lxml python 的官方文档:http://lxml.de/index/html
4、需要安装c语言库 pip install lxml

初步使用

我们利用它来解析HTML代码,简单示例:

html = '''
<div class="Sq_leftNav_forum"><ul class="Sq_lineBox Sq_leftNav_forumList"><li><a href="/shuo/forum/00B002">找对象</a></li><li><a href="/shuo/forum/001002">新鲜事</a></li><li><a href="/shuo/forum/001004">同城互助</a></li><li><a href="/shuo/forum/007005">同城活动</a></li><li><a href="/shuo/forum/00D001">虞城有爱</a></li><li><a href="/shuo/forum/010004">二手闲置</a></li><li><a href="/shuo/forum/010001">找工作</a></li><li><a href="/shuo/forum/00B001">情感</a></li><li><a href="/shuo/forum/002001001">美食</a></li></ul>
</div>
'''
# 使用lxml的etree模块
from lxml import etree# 利用etree.HTML()构造一个xpath解析对象(转为xml文档)
xml_doc = etree.HTML(html)
# print(xml_doc)# etree.tostring()输出修正后的HTML代码
html_doc = etree.tostring(xml_doc)
# print(html_doc)   # 自动补全了body,html标签
# print(type(html_doc))  # bytes类型print(html_doc.decode('utf-8'))    # 利用decode()方法将其转成str类型
print(type(html_doc.decode('utf-8')))
<html><body><div class="Sq_leftNav_forum"><ul class="Sq_lineBox Sq_leftNav_forumList"><li><a href="/shuo/forum/00B002">&#25214;&#23545;&#35937;</a></li><li><a href="/shuo/forum/001002">&#26032;&#40092;&#20107;</a></li><li><a href="/shuo/forum/001004">&#21516;&#22478;&#20114;&#21161;</a></li><li><a href="/shuo/forum/007005">&#21516;&#22478;&#27963;&#21160;</a></li><li><a href="/shuo/forum/00D001">&#34398;&#22478;&#26377;&#29233;</a></li><li><a href="/shuo/forum/010004">&#20108;&#25163;&#38386;&#32622;</a></li><li><a href="/shuo/forum/010001">&#25214;&#24037;&#20316;</a></li><li><a href="/shuo/forum/00B001">&#24773;&#24863;</a></li><li><a href="/shuo/forum/002001001">&#32654;&#39135;</a></li></ul>
</div>
</body></html>
<class 'str'>

文件读取

除了直接读取字符串,lxml还支持从文件里读取内容,我们新建一个hello.html

from lxml import etree
# etree.parse()读取外部文件
html = etree.parse('./hello.html')
# print(type(html))
# print(html)# 调用tostring()方法即可输出修正后的HTML代码
result = etree.tostring(html)
# print(result)
print(result.decode('utf-8'))
<div class="Sq_leftNav_forum"><ul class="Sq_lineBox Sq_leftNav_forumList"><li><a href="/shuo/forum/00B002">&#25214;&#23545;&#35937;</a></li><li><a href="/shuo/forum/001002">&#26032;&#40092;&#20107;</a></li><li><a href="/shuo/forum/001004">&#21516;&#22478;&#20114;&#21161;</a></li><li><a href="/shuo/forum/007005">&#21516;&#22478;&#27963;&#21160;</a></li><li><a href="/shuo/forum/00D001">&#34398;&#22478;&#26377;&#29233;</a></li><li><a href="/shuo/forum/010004">&#20108;&#25163;&#38386;&#32622;</a></li><li><a href="/shuo/forum/010001">&#25214;&#24037;&#20316;</a></li><li><a href="/shuo/forum/00B001">&#24773;&#24863;</a></li><li><a href="/shuo/forum/002001001">&#32654;&#39135;</a></li></ul>
</div>
html = '''
<div><ul><li class="Sq_leftNav_forum1"><a href="/shuo/forum/00B002">找对象</a></li><li class="Sq_leftNav_forum2"><a href="/shuo/forum/001002">新鲜事</a></li><li class="Sq_leftNav_forum1"><a href="/shuo/forum/001004">同城互助</a></li><li class="Sq_leftNav_forum2"><a href="/shuo/forum/007005">同城活动</a></li><li class="Sq_leftNav_forum1"><a href="/shuo/forum/00D001">虞城有爱</a></li></ul>
</div>
'''
from lxml import etreehtml_doc = etree.HTML(html) # xml
result = html_doc.xpath('//li')
# print(result)
for i in result:r = etree.tostring(i).decode('utf-8')print(r)
<li class="Sq_leftNav_forum1"><a href="/shuo/forum/00B002">&#25214;&#23545;&#35937;</a></li><li class="Sq_leftNav_forum2"><a href="/shuo/forum/001002">&#26032;&#40092;&#20107;</a></li><li class="Sq_leftNav_forum1"><a href="/shuo/forum/001004">&#21516;&#22478;&#20114;&#21161;</a></li><li class="Sq_leftNav_forum2"><a href="/shuo/forum/007005">&#21516;&#22478;&#27963;&#21160;</a></li><li class="Sq_leftNav_forum1"><a href="/shuo/forum/00D001">&#34398;&#22478;&#26377;&#29233;</a></li>

2、继续获取

  • 标签的所有class属性
  • html_doc = etree.HTML(html) # xml
    result = html_doc.xpath('//li/@class')
    print(result)
    
    ['Sq_leftNav_forum1', 'Sq_leftNav_forum2', 'Sq_leftNav_forum1', 'Sq_leftNav_forum2', 'Sq_leftNav_forum1']
    

    3、获取

  • 标签下的标签里的所有href
  • html_doc = etree.HTML(html) # xml
    result = html_doc.xpath('//li/a/@href')
    print(result)
    
    ['/shuo/forum/00B002', '/shuo/forum/001002', '/shuo/forum/001004', '/shuo/forum/007005', '/shuo/forum/00D001']
    

    4、继续获取

  • 标签下href为/shuo/forum/00B002的标签的文本内容
  • html_doc = etree.HTML(html) # xml
    result = html_doc.xpath('//li/a[@href="/shuo/forum/00B002"]/text()')
    print(result)
    
    ['找对象']
    

    注意:只要涉及到条件,加[]
    只要获取属性值,加@
    通过text()取内容

http://www.lryc.cn/news/64359.html

相关文章:

  • 网络编程之 Socket 套接字(使用数据报套接字和流套接字分别实现一个小程序(附源码))
  • What Are Docker Image Layers?
  • 范数详解-torch.linalg.norm计算实例
  • postgresdb备份脚本
  • MATLAB程序员投简历的技巧解析,如何写出有亮点的简历
  • 颜色空间转换RGB-YCbCr
  • 年薪40万程序员辞职炒股,把一年工资亏光了,得了抑郁症,太惨了
  • 10分钟如何轻松掌握JMeter使用方法?
  • [NLP]如何训练自己的大型语言模型
  • LeetCode1047. 删除字符串中的所有相邻重复项
  • 3。数据结构(3)
  • QT停靠窗口QDockWidget类
  • 【LeetCode】139. 单词拆分
  • 【三维重建】NeRF原理+代码讲解
  • IntelliJ IDEA 社区版2021.3配置SpringBoot项目详细教程及错误解决方法
  • Qt中QDebug的使用
  • vue使用路由的query配置项时如何清除地址栏的参数
  • Redis-列表(List)
  • ripro主题修改教程-首页搜索框美化教程
  • 写作业用白光还是暖光?盘点色温4000K的护眼台灯
  • Java时间类(一)-- SimpleDateFormat类
  • 07 Kubernetes 网络与服务管理
  • 并发编程之Atomic原子操作类
  • 管家婆辉煌Ⅱ 13.32版安装方法
  • 常见的接口优化技巧思路
  • 【Java EE】-使用Fiddler抓包以及HTTP的报文格式
  • Java异步编程
  • C++类与对象(二)——构造函数与析构函数
  • c++标准模板(STL)(std::array)(四)
  • vue3计算属性