文章目录
一、XML和HTML的对比1.什么是xml?2.XML 和 HTML 的区别2.1 语法要求不同2.2 标记不同2.3 作用不同
二、XPATH1.什么是XPath2.开始使用的前提2.1 文本转换为文档树2.2 外部文件转换为文档树
3.介绍etree中的其他内容3.1 元素3.2 路径表达式3.3 通配符(匹配任意节点)3.4 谓语3.5 多个路径3.6 常用函数举例3.7 获取文本内容的两种方式( text() 和 .text)3.8 etree.tostring()将对象转为字符串3.9 xpath中的轴
一、XML和HTML的对比
1.什么是xml?
xml称为可拓展性标记语言xml具有自描述特性,是一种半结构化数据XML 是一种标记语言,很类似 HTMLXML 的设计宗旨是传输数据,而非显示数据XML 的标签需要我们自行定义。XML 是 W3C 的推荐标准
W3School官方文档:http://www.w3school.com.cn/xml/index.asp
2.XML 和 HTML 的区别
他们两者都是用于操作数据或者结构数据,在结构上大致相同的,但他们在本质上却存在着明显的区别。
2.1 语法要求不同
在html中不区分大小写,在xml中严格区分在html中,有时不严格,如果上下文清楚地显示出段落或者列表键在何处结尾,那么你可以省略右半部分闭合标签。在xml中,是严格的树状结构,绝对不能省略任何标记。在xml中,拥有单个标记二没有匹配的结束标记的元素必须用一个/字符作为结尾。在xml中,属性值必须分装在引号中。在html中,引号可用可不用。在html中属性名可以不带属性值,xml必须带xml文档中,空白部分不会被解析器自动删除,但是html是过滤掉空格的
总结:xml的语法要求更严格。
2.2 标记不同
html使用固有的标记,xml没有固有标记
2.3 作用不同
xml主要用来传输数据html主要用来显示数据,以及更好的显示数据
二、XPATH
1.什么是XPath
Xath (XML Path Language) 是一种语法,用来提取xml或者html内容的语法。
W3School官方文档:http://www.w3school.com.cn/xpath/index.asp
2.开始使用的前提
需要把xml或者html转换成文档树对象
2.1 文本转换为文档树
from lxml
import etree
if __name__
== '__main__':
doc
='''
<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>
'''
html
= etree
.HTML
(doc
)
html2
=etree
.XML
(doc
)
result
= etree
.tostring
(html
)
print(str(result
,'utf-8'))
2.2 外部文件转换为文档树
index.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">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>
test.py
from lxml
import etree
html
= etree
.parse
('./index.html')
result
= etree
.tostring
(html
, pretty_print
=True)
print(result
)
3.介绍etree中的其他内容
3.1 元素
html ---> <html> ...</html>
div ---> <div> ...</div>
a ---> <a> ...</a>
这里的元素和html中的标签一个意思。单独的元素是无法表达一个路径的,所以单独的元素不能独立使用
3.2 路径表达式
表达式描述
nodename选取此节点的所有子节点/从根节点选取//从匹配选择的当前节点选择文档中的节点,而不考虑他们的位置.选取当前节点…选取当前节点的父节点@选取属性
3.3 通配符(匹配任意节点)
通配符描述
*任意元素@*任意属性node()任意子节点(元素,属性,内容)
3.4 谓语
使用中括号来限定元素,称为谓语
表达式描述
//a[3]代表子元素排在第3个位置的元素//a[last()]last() 代表子元素排在最后个位置的元素//a[last()-1]和上面同理,代表倒数第二个//a[position() < 3]位置序号小于3,也就是前两个,这里我们可以看出xpath中的序列是从1开始//a[@href]拥有href的元素//a[@href=‘www’]href属性值为’www’的元素//book[@price>2]price值大于2的元素
3.5 多个路径
用 | 连接两个表达式,可以进行 或 匹配
//book/title | //book/price
3.6 常用函数举例
函数举例描述
contains()//a[contains(@class,‘a’)] 或 //a[contains(text(),‘b’)]a标签类名包含a字符 或 a标签文字中有包含b的start-with()//a[starts-with(@class,‘a’)]a标签类名开头是a字符的,注意没有ends-withtext()//span/text()span标签下的文字last()//span[last()]取最后一个span标签position()//span[position()❤️] 或 //li[position()=2]取前两个位置的span标签 或 li中第二个位置node()//ul/node()返回ul的所有子节点,不管这个子节点是什么类型(熟悉,元素,内容)
3.7 获取文本内容的两种方式( text() 和 .text)
from lxml
import etree
doc
= '''
<div>
<ul class='ul items'>
<li class="item-0 active"><a href="link1.html">1</a></li>
<li class="item-1"><a href="link2.html">2</a></li>
<li class="item-1"><a href="link4.html">4</a></li>
wwwww
</ul>
</div>
'''
html
= etree
.XML
(doc
)
print(html
.xpath
("//a/text()"))
print(html
.xpath
("//a")[0].text
)
print(html
.xpath
("//ul")[0].text
)
print(html
.xpath
("//ul/text()"))
3.8 etree.tostring()将对象转为字符串
from lxml
import etree
doc
= '''
<div>
<ul class='ul items'>
<li class="item-0 active"><a href="link1.html">1</a></li>
<li class="item-1"><a href="link2.html">2</a></li>
<li class="item-1"><a href="link4.html">4</a></li>
wwwww
</ul>
</div>
'''
html
= etree
.HTML
(doc
)
ele
= etree
.tostring
(html
.xpath
('//li[1]')[0])
print ele
3.9 xpath中的轴
总共有八个轴关键字,parent,child,ancestor祖先,descendant后裔,following,following-sibling兄弟姐妹,preceding,preceding-sibling。具体含义如下:
表达式描述
parent::div上层父节点,你那叫div的亲生爸爸,最多有一个;child::div下层所有子节点,你的所有亲儿子中叫div的;ancestor::div上面所有直系节点,是你亲生爸爸或者你亲爹或者你亲爹的爸爸中叫div的;descendant::div下面所有节点,你的后代中叫div的,不包括你弟弟的后代;following::div自你以下页面中所有节点叫div的;following-sibling::div同层下节点,你所有的亲弟弟中叫div的;preceding::div同层上节点,你所有的亲哥哥以及他们的后代中叫div的;preceding-sibling::div同层上节点,你所有的亲哥哥中叫div的;
轴参考文章:https://www.bbsmax.com/A/kvJ33W3nJg/