文章目录

  • 一. XML
    • 1. XML 和 HTML 的区别
    • 2. XML文档示例
    • 3. HTML DOM 模型示例
    • 4. XML的节点关系
  • 二. 什么是XPath?
    • 1. 选取节点
    • 2. 谓语(Predicates)
    • 3. 选取未知节点
    • 4. 选取若干路径
    • 5. XPath的运算符
  • 三. lxml库
    • 1. 初步使用
    • 2. 文件读取
  • 四. XPath实例测试
    • 1. 获取所有的 < li> 标签
    • 2. 继续获取< li> 标签的所有 class属性
    • 3. 继续获取< li>标签下href 为 link1.html 的 < a> 标签
    • 4. 获取< li> 标签下的所有 < span> 标签
    • 5. 获取 < li> 标签下的< a>标签里的所有 class
    • 6. 获取最后一个 < li> 的 < a> 的 href
    • 7. 获取倒数第二个元素的内容
    • 8. 获取 class 值为 bold 的标签名

一. XML

有人说,我正则用的不好,处理HTML文档很累,有没有其他的方法?

有!那就是XPath,我们可以先将 HTML文件 转换成 XML文档,然后用 XPath 查找 HTML 节点或元素。

  1. XML 指可扩展标记语言(EXtensible Markup Language)
  2. XML 是一种标记语言,很类似 HTML
  3. XML 的设计宗旨是传输数据,而非显示数据
  4. XML 的标签需要我们自行定义。
  5. XML 被设计为具有自我描述性。
  6. XML 是 W3C 的推荐标准

W3School官方文档:http://www.w3school.com.cn/xml/index.asp

1. XML 和 HTML 的区别

在这里插入图片描述

2. 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. Rowling</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>  <author>Vaidyanathan Nagarajan</author>  <year>2003</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>

3. HTML DOM 模型示例

HTML DOM 定义了访问和操作 HTML 文档的标准方法,以树结构方式表达 HTML 文档。
在这里插入图片描述

4. XML的节点关系

下面一个简单的XML例子中:

<?xml version="1.0" encoding="utf-8"?><bookstore><book><title>Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book></bookstore>
  1. 父(Parent) 每个元素以及属性都有一个父。book 元素是 title、author、year 以及 price 元素的父。
  2. 子(Children)元素节点可有零个、一个或多个子。title、author、year 以及 price 元素都是 book 元素的子。
  3. 同胞(Sibling)拥有相同的父的节点。title、author、year 以及 price 元素都是同胞。
  4. 先辈(Ancestor)某节点的父、父的父,等等。title 元素的先辈是 book 元素和 bookstore 元素。
  5. 后代(Descendant)某个节点的子,子的子,等等。bookstore 的后代是 book、title、author、year 以及 price 元素。

二. 什么是XPath?

XPath (XML Path Language) 是一门在 XML 文档中查找信息的语言,可用来在 XML 文档中对元素和属性进行遍历。

W3School官方文档:http://www.w3school.com.cn/xpath/index.asp

XPath 开发工具
开源的XPath表达式编辑工具:XMLQuire(XML格式文件可用)
Chrome插件 XPath Helper
Firefox插件 XPath Checker

1. 选取节点

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

下面列出了最常用的路径表达式:

在这里插入图片描述

在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:
在这里插入图片描述

2. 谓语(Predicates)

谓语用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在方括号中。

在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

在这里插入图片描述

3. 选取未知节点

XPath 通配符可用来选取未知的 XML 元素。

在这里插入图片描述
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

4. 选取若干路径

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

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

在这里插入图片描述

5. XPath的运算符

下面列出了可用在 XPath 表达式中的运算符:

在这里插入图片描述

这些就是XPath的语法内容,在运用到Python抓取时要先转换为xml。

三. lxml库

lxml 是 一个HTML/XML的解析器,主要的功能是如何解析和提取 HTML/XML 数据。

lxml和正则一样,也是用 C 实现的,是一款高性能的 Python HTML/XML 解析器,我们可以利用之前学习的XPath语法,来快速的定位特定元素以及节点信息。

lxml python 官方文档:http://lxml.de/index.html

需要安装C语言库,可使用 pip 安装:pip install lxml (或通过wheel方式安装)

1. 初步使用

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

from lxml import etreetext = '''
<div><ul><li class="item-0"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签</ul></div>
'''#利用etree.HTML,将字符串解析为HTML文档
print('------1------')
print(text)
print (type(text))html = etree.HTML(text)
print('-----2-------')
print(html)
print (type(html))# 按字符串序列化HTML文档
result = etree.tostring(html)
print('-----3-------')
print(result)
print (type(result))

输出结果:

------1------<div><ul><li class="item-0"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签</ul></div><class 'str'>
-----2-------
<Element html at 0x1e839453708>
<class 'lxml.etree._Element'>
-----3-------
b'<html><body><div>\n    <ul>\n         <li class="item-0"><a href="link1.html">first item</a></li>\n         <li class="item-1"><a href="link2.html">second item</a></li>\n         <li class="item-inactive"><a href="link3.html">third item</a></li>\n         <li class="item-1"><a href="link4.html">fourth item</a></li>\n         <li class="item-0"><a href="link5.html">fifth item</a> # &#27880;&#24847;&#65292;&#27492;&#22788;&#32570;&#23569;&#19968;&#20010; </li> &#38381;&#21512;&#26631;&#31614;\n     </ul>\n </div>\n</body></html>'
<class 'bytes'>

lxml 可以自动修正 html 代码,例子里不仅会补全 li 标签,还添加了 body,html 标签。

2. 文件读取

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

<!-- hello.html --><div><ul><li class="item-0"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>

再利用 etree.parse() 方法来读取文件。

from lxml import etree# 读取外部文件 hello.html
html1 = etree.parse('./hello.html')
result1 = etree.tostring(html1, pretty_print=True)print('--------------------')
print(result1)print('-------如果是文件读取,需要使用prase(),而不是用HTML,否则会出现下边结果:---------')html2 = etree.HTML('./hello.html')
result2 = etree.tostring(html2, pretty_print=True)
print(result2)

运行结果:

--------------------
b'<div>\n    <ul>\n         <li class="item-0"><a href="link1.html">first item</a></li>\n         <li class="item-1"><a href="link2.html">second item</a></li>\n         <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>\n         <li class="item-1"><a href="link4.html">fourth item</a></li>\n         <li class="item-0"><a href="link5.html">fifth item</a></li>\n     </ul>\n </div>\n'
-------如果是文件读取,需要使用prase(),而不是用HTML,否则会出现下边结果:---------
b'<html>\n  <body>\n    <p>./hello.html</p>\n  </body>\n</html>\n'

四. XPath实例测试

1. 获取所有的 < li> 标签

from lxml import etreehtml = etree.parse('hello.html')
print (type(html))  # 显示etree.parse() 返回类型result = html.xpath('//li')print (result)  # 打印<li>标签的元素集合
print (len(result))
print (type(result))
print (type(result[0]))

输出结果:

<class 'lxml.etree._ElementTree'>
[<Element li at 0x21658f02608>, <Element li at 0x21658f02708>, <Element li at 0x21658f02748>, <Element li at 0x21658f02788>, <Element li at 0x21658f027c8>]
5
<class 'list'>
<class 'lxml.etree._Element'>

2. 继续获取< li> 标签的所有 class属性

from lxml import etreehtml = etree.parse('hello.html')
result = html.xpath('//li/@class')print(result)
print(type(result))

运行结果:

['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']
<class 'list'>

3. 继续获取< li>标签下href 为 link1.html 的 < a> 标签


from lxml import etreehtml = etree.parse('hello.html')
result = html.xpath('//li/a[@href="link1.html"]')print result

输出结果:

[<Element a at 0x23b68132748>]
<class 'list'>

4. 获取< li> 标签下的所有 < span> 标签

from lxml import etreehtml = etree.parse('hello.html')#result = html.xpath('//li/span')
#注意这么写是不对的:
#因为 / 是用来获取子元素的,而 <span> 并不是 <li> 的子元素,所以,要用双斜杠result = html.xpath('//li//span')print(result)
print(type(result))

输出结果:

[<Element span at 0x28d12587508>]
<class 'list'>

5. 获取 < li> 标签下的< a>标签里的所有 class

from lxml import etreehtml = etree.parse('hello.html')
result = html.xpath('//li/a//@class')print(result)
print(type(result))

输出结果:

['bold']
<class 'list'>

6. 获取最后一个 < li> 的 < a> 的 href

from lxml import etreehtml = etree.parse('hello.html')
result = html.xpath('//li/a//@class')print(result)
print(type(result))

输出结果:

['link5.html']
<class 'list'>

7. 获取倒数第二个元素的内容

from lxml import etreehtml = etree.parse('hello.html')
result = html.xpath('//li[last()-1]/a')# text 方法可以获取元素内容
print (result[0].text)
print (type(result[0].text))

输出结果:

fourth item
<class 'str'>

8. 获取 class 值为 bold 的标签名

from lxml import etreehtml = etree.parse('hello.html')result = html.xpath('//*[@class="bold"]')# tag方法可以获取标签名
print (result[0].tag)
print (type(result[0].tag))

输出结果:

span
<class 'str'>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/452027.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/452027.shtml
英文地址,请注明出处:http://en.pswp.cn/news/452027.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实体与属性间的划分原则

为了简化E-R图的处置&#xff0c;现实世界的事物能作为属性对待的&#xff0c;尽量作为属性对待。 两条准则&#xff1a; &#xff08;1&#xff09;作为属性&#xff0c;不能再具有需要描述的性质。属性必须是不可分的数据项&#xff0c;不能包含其他属性。 &#xff08;2&…

编程开发之--java多线程学习总结(5)

4、对继承自Runnable的线程进行锁机制的使用 package com.lfy.ThreadsSynchronize;import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class TicketSellSolution4 implements Runnable {private static int num 50;//创建一个…

软件测试不是一个功能

今天在工作中我对一个同事说&#xff0c;PyDev 2.5.0现在对TDD&#xff08;测试驱动开发&#xff09;提供了很酷的支持了。我并不是一个对TDD很痴迷的倡导者&#xff0c;对其它事物也一样&#xff0c;但仍不免激起了一场讨论。这个家伙&#xff0c;让我们暂叫他约翰&#xff0c…

Linux 操作系统基础知识

1.操作系统总体介绍 •CPU&#xff1a; 就像人的大脑&#xff0c;主要负责相关事情的判断以及实际处理的机制。查询指令&#xff1a; cat /proc/cpuinfo•内存&#xff1a; 大脑中的记忆区块&#xff0c;将皮肤、眼睛等所收集到的信息记录起来的地方&#xff0c;以供CPU进行判断…

Transaction 那点事儿,Spring事务管理

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Transaction 也就是所谓的事务了&#xff0c;通俗理解就是一件事情。从小&#xff0c;父母就教育我们&#xff0c;做事情要有始有终&…

网络爬虫--12.【XPath实战】获取百度贴吧中的图片

用XPath来做一个简单的爬虫&#xff0c;我们尝试爬取某个贴吧里的所有帖子&#xff0c;并且将该这个帖子里每个楼层发布的图片下载到本地。 #codingutf-8 import requests from lxml import etree import jsonclass Tieba:def __init__(self,tieba_name):self.tieba_name tie…

合并分ER图产生的冲突

合并分E-R图 各个局部应用所面向的问题不同&#xff0c;各个子系统的E-R图之间必定会存在许多不一致的地方&#xff0c;称之为冲突。 子系统E-R图之间的冲突主要有三类&#xff1a; ①属性冲突 ②命名冲突 ③结构冲突①属性冲突 属性域冲突&#xff0c;即属性值的类型、取值范围…

8.类定义、属性、初始化和析构

类定义 类 是一个独立存放变量(属性/方法)的空间 封装&#xff1a; 类可以把各种对象组织在一起&#xff0c;作为类的属性&#xff0c;通过 . (点)运算符来调用类中封装好的对象 属性&#xff1a; 变量在类中称为属性&#xff0c;但是类中的属性不仅仅只包含变量&#x…

GPL以及Copyleft协议使用率下降明显

根据最新的协议数据分析&#xff0c;不光是GPL&#xff0c;另外一些copyleft&#xff08;AGPL&#xff0c;LGPL 等等&#xff09;协议的使用率在不断下降&#xff0c;并且下降的速度越来越快。 这结果是在意料之中的&#xff0c;因为GPL非常的复杂。越来越多的个人和企业将选择…

概念模型和关系模型

ER模型&#xff08;逻辑模型&#xff09; ER模型的基本元素是&#xff1a;实体、联系和属性 实体&#xff1a;是一个数据对象&#xff0c;指应用中可以区别的客观存在的事物。&#xff08;ER模型中的实体往往是指实体集&#xff09; 实体集&#xff1a;指同一类实体构成的集合…

iOS AutoLayout使用技巧

关于ContentCompressionResistance&#xff0c; ContentHugging运用 如下图效果图&#xff0c;两个Label并列在同一排上&#xff0c;左边label自适应&#xff0c;右边label&#xff08;红色&#xff09;要使得内容全部展示&#xff0c;如果左边label内容很少&#xff0c;那么右…

网络爬虫--13.数据提取之JSON与JsonPATH

文章目录一. 前言二. JSON三. json.loads()四. json.dumps()五. json.dump()六. json.load()七. JsonPath八. JsonPath与XPath语法对比九. 案例分析一. 前言 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式&#xff0c;它使得人们很容易的进行阅读和编写。同时…

vs2017生成sqlserver 2017项目出现.Net SqlClient Data Provider: Msg 10343

一、使用vs2017生成sqlserver 2017项目时由于添加的程序集(CLR集成&#xff0c;可以参考后面给出的链接进行理解) &#xff0c;由于安全权限的配置不正确引发以下的问题: SQL72014: .Net SqlClient Data Provider: Msg 10343, Level 14, State 1, Line 1 针对带有 SAFE 或 EXT…

数据库系统常用的存取方法

1. B树索引存取方法 2. Hash索引存取方法 3. 聚簇存取方法

创建型模式二:工厂方法模式

1. 工厂模式介绍 工厂模式&#xff08;Factory Pattern&#xff09;的意义就跟它的名字一样&#xff0c;在面向对象程序设计中&#xff0c;工厂通常是一个用来创建其他对象的对象。工厂模式根据不同的参数来实现不同的分配方案和创建对象。 在工厂模式中&#xff0c;我们在创建…

spring 的4种事务管理(1种编程式+3种声明式)

见&#xff1a;http://blog.csdn.net/sinat_25926481/article/details/48208619 Spring的4种事务管理&#xff08;1种编程式事务三种声明事务&#xff09; 一、Spring事务的介绍 二、编程式事务xml的配置 注入后直接在service层调用模板的方法使用 三、基于AOP方式的声明式事务…

如何创造出更优秀的用户体验?

对于互联网公司来说&#xff0c;用户体验起到至关重要的作用&#xff0c;能否给用户留下深刻的印象&#xff1b;开发出的产品是否实用、易用&#xff1f;等等这些都是开发者必将思考的话题。当有用性一样的时候&#xff0c;大家的竞争重点就是易用性了&#xff0c;这就是互联网…

java并发编程实战-第三章-对象的共享

3.1可见性 首先我们需要知道的是&#xff0c;java的线程都有自己独立的缓存&#xff0c;线程之间进行共享变量的交互是通过自身和缓存和主存的交互实现的。如果线程的每次更改缓存都刷入主存&#xff0c;主存每次被一个线程的缓存修改&#xff0c;都通知所有的线程刷新自身的缓…

GitHub(从安装到使用)

一、安装Git for Windows&#xff08;又名msysgit&#xff09; 下载地址: https://git-for-windows.github.io/ 在官方下载完后&#xff0c;安装到Windows Explorer integration的时候&#xff0c;将选项中将“Git Bash here”和“Git GUI here”打对勾。 然后就一直next直到Fi…

Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别、不可重复读与幻读的区别

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 spring事务配置的五种方式 前段时间对Spring的事务配置做了比较深入的研究&#xff0c;在此之间对Spring的事务配置虽说也配置过&#x…