如何制作外贸网站 wordpress,wordpress底面有虚线这么办,河南映天建设网站,python免费自学网站目录 1. XPath 概览 2. XPath 常用规则 3. 准备工作 4.实例引入 5.所有节点 6. 子节点 7.父节点 8.属性匹配 9.文本获取 10.属性获取 11.属性多值匹配 12. 多属性匹配 13.按序选择 14. 节点轴选择 结语 1. XPath 概览 XPath 全称 XML Path Language #xff0c;即 XML 路径语言…目录 1. XPath 概览 2. XPath 常用规则 3. 准备工作 4.实例引入 5.所有节点 6. 子节点 7.父节点 8.属性匹配 9.文本获取 10.属性获取 11.属性多值匹配 12. 多属性匹配 13.按序选择 14. 节点轴选择 结语 1. XPath 概览 XPath 全称 XML Path Language 即 XML 路径语言它是一门在 XML 文档中查找信息的语言 它最初是用来搜寻 XML 文档的但是它同样适用于 HTML 文档的搜索XPath 的选择功能十分强大它提供了非常简洁明了的路径选择表达式 另外它还提供了超过 100 个内建函数用于字符串、数值、时间的匹配以及节点、序列的处理 几乎所有我们想要定 的节点者阿以用 XPath 来选择 XPath于1999年11月16日成为 W3C 标准它被设计为供 XSLT、XPointer 以及其他 XML 解析 软件使用更多的文档可以访问其官方网站 xpath cover page - W3C 2. XPath 常用规则 常用的集中规则有 nodename 选择此节点的所有子节点/ 从当前节点选择直接子节点// 从当前节点选择子孙节点. 选取当前节点 .. 选取当前节点的父节点 选取属性 举个例子 //title [lang ergou] 这个就是选择所有标签名为title 并且 lang的属性值为二狗的元素 //title [lang ergou][1] 这个就是选择所有标签名为title 并且 lang的属性值为二狗的元素的第一个元素 //title [lang ergou][1]/href 这个就是选择所有标签名为title 并且 lang的属性值为二狗的元素的第一个元素的href 属性 3. 准备工作 使用之前首先要确保安装好 lxml 库若没有安装 可以参考安装过程 4.实例引入 这里首先导人 lxml 库的 etree 模块然后声明了一段HTML文本调用 HTML 类进行初始化这样就成功构造了一个XPath解析对 这里需要注意的是HTML文本中的最后一个li节点是没有 闭合的但是etree模块可以自动修正HTML文本from lxml import etree
text
div
ul
li classitem-0a hreflink1. htmlfirst item/a/li
li classitem-1a hreflink2.html second item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/divhtml etree.HTML(text)
result etree.tostring(html)
print(result.decode(utf-8)) 这里我们调用 tostring()方法即可输出修正后的HTML代码但是结果是 bytes 类型 这里利用 decode()方法将其转成 str 类型结果如下可以看到经过处理之后 li 节点标签被补全并且还向动添加了 body,html 节点 另外也可以直接读取文本文件进行解析示例如下:
from lxml import etree
html etree.parse(./test.html,etree.HTMLParser())其中test.html为上述的
div
ul
li classitem-0a hreflink1. htmlfirst item/a/li
li classitem-1a hreflink2.html second item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/divresult etree.tostring(html)
print(result.decode(utf-8))
返回 至于有 #13应该是我手打不知哪错了排除这个结果与上面略有不同就是多了一个声明DOCTYPE 不过对解析没有任何影响
5.所有节点 我们一般会用刀 // 开头的 XPath 规则来选取所有符合要求的节点 这里以上面的 HTML 文本为例 如果要选取所有节点可以这样实现from lxml import etree
html etree.parse(./test.html,etree.HTMLParser())其中test.html为上述的
div
ul
li classitem-0a hreflink1. htmlfirst item/a/li
li classitem-1a hreflink2.html second item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/div
result html.xpath(//*)
print(result) 返回 这里使用代表匹配所有节点也就是整个 HTML 文本中的所有节点都会被获取 可以看到返 回形式是一个列表每个元素是 Element 类型其后跟了节点的名称如 html、body、div、ul、li、a等所有节点都包含在列表中了 当然 此处匹配也可以指定节点名称。如果想获取所有 li 节点示例如下 from lxml import etree
html etree.parse(./test.html,etree.HTMLParser())其中test.html为上述的
div
ul
li classitem-0a hreflink1. htmlfirst item/a/li
li classitem-1a hreflink2.html second item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/div
result html.xpath(//li)
print(result)
print(result[0]) 返回: 这里可以看到提取结果是一个列表形式其中每个元素都是 Element 对象。如果要取出其中一个对象 可以直接用中括号加索引如[0]。 6. 子节点 我们通过 / 或 // 即可查找元素的子节点或子孙节点。假如现在想选择 li 节点的所有直接a子节点 可以这样实现 from lxml import etree
html etree.parse(./test.html,etree.HTMLParser())其中test.html为上述的
div
ul
li classitem-0a hreflink1. htmlfirst item/a/li
li classitem-1a hreflink2.html second item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/div
result html.xpath(//li/a)
print(result) 返回 此处的 / 用于选取直接子节点 如果要获取所有子孙节点就可以使用 // 例如要获取 ul 节点下的所有子孙a节点可以这样实现 from lxml import etree
html etree.parse(./test.html,etree.HTMLParser())其中test.html为上述的
div
ul
li classitem-0a hreflink1. htmlfirst item/a/li
li classitem-1a hreflink2.html second item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/div
result html.xpath(//ul//a)
print(result) 运行结果 但是如果这里用 //ul/a 就无法获取任何结果了 因为 / 用于获取直接子节点而在 节点下没 有直接 子节点只有 li 节点所以无法获取任何匹配结果代码如下 from lxml import etree
html etree.parse(./test.html,etree.HTMLParser())其中test.html为上述的
div
ul
li classitem-0a hreflink1. htmlfirst item/a/li
li classitem-1a hreflink2.html second item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/div
result html.xpath(//ul/a)
print(result) 运行结果为 7.父节点 我们知道通过连续的 / 或 // 可以查找子节点或子孙节点那么假如我们知道了子节点怎样来查找父节点呢这可以用 .. 来实现 比如现在首先选中 href 属性为 link4.html 节点然后再获取其父节点然后再获取其 class 属性相关代码如下 from lxml import etree
html etree.parse(./test.html,etree.HTMLParser())其中test.html为上述的
div
ul
li classitem-0a hreflink1. htmlfirst item/a/li
li classitem-1a hreflink2.html second item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/divresult html.xpath(//a[hreflink4.html]/../class)
print(result) 返回 同时我们也可以通过 parent:: 来获取父节点: from lxml import etree
html etree.parse(./test.html,etree.HTMLParser())其中test.html为上述的
div
ul
li classitem-0a hreflink1.htmlfirst item/a/li
li classitem-1a hreflink2.htmlsecond item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/divresult html.xpath(//a[hreflink4.html]/parent::*/class)
print(result) 8.属性匹配 在选取的时候我们还可以用符号进行属性过滤。比如这里如果要选取 class为item-1的li 节点可以这样实现 from lxml import etree
html etree.parse(./test.html,etree.HTMLParser())其中test.html为上述的
div
ul
li classitem-0a hreflink1.htmlfirst item/a/li
li classitem-1a hreflink2.htmlsecond item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/divresult html.xpath(//li[classitem-0])
print(result) 这里我们通过加入[class item -0”]限制了节点的 class 属性为 item-0 而 HTML 文本中符合 条件的 li 节点有两个所以结果应该返回两个匹配到的元素 结果如下 可见匹配结果正是两个至于是不是那正确的两个后面再验证 。 9.文本获取 用 XPath 中的 text() 方法获取节点中的文本接下来尝试获取前面 li 节点中的文本相关 代码如下 from lxml import etree
html etree.parse(./test.html,etree.HTMLParser())其中test.html为上述的
div
ul
li classitem-0a hreflink1.htmlfirst item/a/li
li classitem-1a hreflink2.htmlsecond item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/divresult html.xpath(//li[classitem-0]/text())
print(result) 运行结果 奇怪的是我们并没有获取到任何文本却有WIN回车换行这是为什么呢因为 XPath中text()前面是而此处的含义是选取直接子节点很明显li的直接子节点都是a节点文本都是在a节点内部的所以这里匹配到的结果就是被修正的li节点内部的符号因为自动修正的 li 节点的尾标签有WIN回车换行。 即选中的是这两个节点 li classitem-0a hreflink1.htmlfirst item/a/li
li classitem-0a hreflink5.htmlfifth item/a 其中一个节点因为向动修正 li 节点的尾标签添加的时候换行了所以提取文本得到的唯一结果就是 li 节点的尾标签和a节点的尾标签之间的换行符。 因此如果想获取 li 节点内部的文本就有两种方式一种是先选取a节点再获取文本另一 种就是使用 // 接下来我们来看下二者的区别 首先 选取至a节点再获取文本代码如下 from lxml import etree
html etree.parse(./test.html,etree.HTMLParser())其中test.html为上述的
div
ul
li classitem-0a hreflink1.htmlfirst item/a/li
li classitem-1a hreflink2.htmlsecond item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/divresult html.xpath(//li[classitem-0]/a/text())
print(result) 输出为 可以看到这里的返回值是两个内容都是属性为 item-o的 li 节点的文本这也印证了前面属性匹配的结果是正确的。 再来看下用另一种方式即使用 // 选取的结果代码如下 from lxml import etree
html etree.parse(./test.html,etree.HTMLParser())其中test.html为上述的
div
ul
li classitem-0a hreflink1.htmlfirst item/a/li
li classitem-1a hreflink2.htmlsecond item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/divresult html.xpath(//li[classitem-0]//text())
print(result) 输出 不出所料这里的返回结果是3个可想而知这里是选取所有子孙节点的文本其中前两个就 li 的子节点a节点内部的文本另外一个就是最后一个 li 节点内部的文本即换行符。 10.属性获取 我们知道用 text() 可以获取节点内部文本那么节点属性该怎样获取呢其实还是用符号就可。例如我们想获取所有 li 节点下所有a节点的 href 属性代码如下 from lxml import etree
html etree.parse(./test.html,etree.HTMLParser())其中test.html为上述的
div
ul
li classitem-0a hreflink1.htmlfirst item/a/li
li classitem-1a hreflink2.htmlsecond item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/divresult html.xpath(//li/a/href)
print(result) 返回 注意此处和属性匹配的方法不同属性匹配是中括号加属性名和值来限定某个属性如[hreflinkl.html ”]而此处的href 指的是获取节点的某 个属性二者需要做好区分 11.属性多值匹配 有时候某些节点的某个属性可能有多个值例如: from lxml import etree
text
li classli li-firsta href link.htmlfirst item/a/li html etree .HTML(text)
result html.xpath(//li[contains(class,li)]/a/text())
print(result) 这样通过 contains() 方法第一个参数传入属性 名称第二个参数传入属性值只要此属性包含所传入的属性值就可以完成匹配了运行结果如下 注此种方式在某个节点的某个属性有多个值时经常用到如某个节点的 class 属性通常有多个。 12. 多属性匹配 我们可能还遇到一种情况那就是根据多个属性确定一个节点这时就需要同时匹配多个属性。此时可以使用运算符 and 来连接示例如下 from lxml import etree
text
li classli li-first nameitema href link.htmlfirst item/a/li html etree .HTML(text)
result html.xpath(//li[contains(class,li) and nameitem]/a/text())
print(result) 这里的 li 节点又增加了1个属性 name 要确定这个节点 需要同时根据 clas和name 属性来选择一个条件是 class 属性里面包含 li 字符串另一个条件是 name 属性为 item 字符串二者需要同时满足需要用 and 操作符相连相连之后置于中括号内进行条件筛选 运行结果如下 xpath运算符有哪些呢 13.按序选择 有时候我们在选择的时候某些属性可能同时匹配了多个节点但是只想要其中的某个节点如第二个节点或者最后一个节点这时该怎么办呢 这时可以利用中括号传入索引的方法获取特定次序的节点示例如下 from lxml import etree
text
div
ul
li classitem-0a hreflink1.htmlfirst item/a/li
li classitem-1a hreflink2.htmlsecond item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/divhtml etree.HTML(text)
#序号是以1开头的不是以0开头
result html.xpath(//li[1]/a/text()) #第一个 li 节点
print(result)
result html.xpath(//li[last()]/a/text()) #最后一个 li 节点
print(result)
result html.xpath(//li[position()3]/a/text()) #选取位置小于3的 li 节点也就是1和2的节点
print(result)
result html.xpath(//li[last()-2]/a/text()) #选取倒数第三个的节点last()是最后一个所有last()-2就是倒数第三个
print(result) 运行结果为 14. 节点轴选择 XPath 提供了很多节点轴选择方法包括获取子元素 、兄弟元素、父元素、祖先元素等示例如下 from lxml import etree
text
div
ul
li classitem-0a hreflink1.htmlspanfirst item/span/a/li
li classitem-1a hreflink2.htmlsecond item/a/li
li classitem-inactivea hreflink3.htmlthird item/a/li
li classitem-1a hreflink4.htmlfourth item/a/li
li classitem-0a hreflink5.htmlfifth item/a
/ul
/divhtml etree.HTML(text)
#序号是以1开头的不是以0开头
result html.xpath(//li[1]/ancestor::*)
第一次选择时调用了ancestor轴可以获取所有祖先节点 其后需要跟两个冒号然后是节点的选择器这里我们直接使用*表示匹配所有节点因此返回结果是第一个 li 节点的所有祖先节点包括 html、body、div、ul
print(result)
result html.xpath(//li[1]/ancestor::div)
第二次选择时又加了限定条件这次在冒号后面加了 div 这样得到的结果就只有 div这个祖先节点了
print(result)
result html.xpath(//li[1]/attribute::*)
第三次选择时调用了 attribute 轴可以获取所有属性值其后跟的选择器还是*这代获取节点的所有属性返回值就是 li 节点的所有属性值
print(result)
result html.xpath(//li[1]/child::a[hreflink1.html])
第四次选择时调用了 child 轴可以获取所有直接子节点 这里又加了限定条件选 href 属性为 linkl.html的a节点
print(result)
result html.xpath(//li[1]/descendant::span)
第五次选择时调用了 descendant 轴可以获取所有子孙节点 这里又加了限定条件获取 span 节点所以返回的结果只包含 span 节点而不包含a节点
print(result)
result html.xpath(//li[1]/following::*[2])
第六次选择时调用 following 轴可以获取当前节点之后的所有节点 这里虽然使用的是*匹配但又加了索引选择所以只获取了第二个后续节点
print(result)
result html.xpath(//li[1]/following-sibling::*)
第七次选择时调用 fo llowing -s ibling 可以获取当前节点之后的所有同级节点,使用*匹配所以获取了所有后续同级节点
print(result) 运行结果 结语 到这里我们基本把会用到的xpath选择器介绍完了。xpath功能非常强大内置函数非常多熟练使用后会大大提升HTML信息的提取效率。 如果想查询更多 XPath 的用法可以查看XPath 教程 如果想查询更多 .Pyt on xml 库的用法可以查看lxml - Processing XML and HTML with Python