当前位置:   article > 正文

pythonlxml库_Python爬虫(十二)_XPath与lxml类库

['harry potter'] xpath 去掉括号

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

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

什么是XML

XML指可扩展标记语言(Extensible Markup Language)

XML是一种标记语言,很类似HTML

XML的设计宗旨是传输数据,而非显示数据。

XML的标签需要我们自行定义。

XML被设计为具有自我描述性。

XML是W3C的推荐标准。

XML和HTML的区别

数据格式

描述

设计目标

XML

Extensible Markup Language (可扩展标记语言)

被设计为传输和存储数据,其焦点是数据的内容。

HTML

HyperText Markup Language(超文本标记语言)

显示数据以及如何更好显示数据。

HTML DOM

Document Object Model for HTML (文档对象模型)

通过 HTML DOM,可以访问所有的 HTML 元素,连同它们所包含的文本和属性。可以对其中的内容进行修改和删除,同时也可以创建新的元素。

XML文档实例

Everyday Italian

Giada De Laurentiis

2005

30.00

Harry Potter

J K. Rowling

2005

29.99

XQuery Kick Start

James McGovern

Per Bothner

Kurt Cagle

James Linn

Vaidyanathan Nagarajan

2003

49.99

Learning XML

Erik T. Ray

2003

39.95

HTML DOM模型示例

HTML DOM定义了访问和操作HTML文档的标准方法,以树结构方式表达了HTML文档。

aabafbb640c2

HTML DOM

XML的节点关系

1.父(Parent)

每个元素以及属性都有一个父。

下面是一个简单的XML例子中,book元素时title、author、year以及price

Harry Potter

J K. Rowling

2005

29.99

2.子(Children)

元素节点可能有零个、一个或多个子。

在下面的例子中,title、author、year以及price元素都是book元素的子:

Harry Potter

J K. Rowling

2005

29.99

3.同胞(Sibling)

拥有相同的父的节点

在下面的例子中,title、author、year以及price元素都是同胞:

Harry Potter

J K. Rowling

2005

29.99

4.先辈(Ancestor)

某节点的父、父的父,等等。

在下面的例子中,title元素的先辈是book元素和bookstore元素:

Harry Potter

J K. Rowling

2005

29.99

5.后代

某个节点的子,子的子,等等。

在下面的例子中,bookstore的后代是book、title、author、year以及price元素:

Harry Potter

J K. Rowling

2005

29.99

什么是XPath?

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

XPath 开发工具

开源的XPath表达式编辑工具:XML Quire(XML格式文件可用)

Chrome插件Xpath Helper

Firefox插件Xpath Checker

选取节点

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

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

表达式

描述

nodename

选取此节点的所有子节点

/

从根节点选取

//

从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。

.

选取当前节点。

..

选取当前节点的父节点

@

选取属性

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

路径表达式

描述

bookstore

选取bookstore元素的所有子节点。

/bookstore

选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!

bookstore/book

选取属于bookstore的子元素的所有book元素

//book

选取所有book子元素,而不管它们在文档中的位置

bookstore//book

选择属于bookstore元素的后代的所有bok元素,而不管它们位于bookstore之下的什么位置

//@lang

选取名为lang的所有属性。

谓语(Predicates)

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

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

路径表达式

结果

/bookstore/book[1]

选取属于bookstore子元素的第一个book元素。

/bookstore/book[last()]

选取数据bookstore子元素的最后一个book元素

/bookstore/book[last()-1]

选取属于bookstore元素的倒数第二个book元素

/bookstore/book[position()<3]

选取最前面的两个属于bookstore元素的子元素book元素

//title[@lang]

选取所有拥有名为lang的属性的title元素

//title[@lang="eng"]

选取所有title元素,且这些元素拥有值为eng的lang属性

/bookstore/book[price>35.00]

选取所有bookstore元素的book元素,且其中的price元素的值必须大于35.00

/bookstore/book[price>35.00]/title

选取bookstore元素中的book元素的所有title元素,且其中的price元素的值必须大于35.00

选取未知节点

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

通配符

描述

*

匹配任何元素节点

@*

匹配任何属性节点

node()

匹配任何类型的节点

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

路径表达式

结果

/bookstore/*

选取bookstore元素的所有子元素

//*

选取文档中的所有元素

title[@*]

选取所有带属性的title元素

选取若干路径

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

实例

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

路径表达式

结果

'//book/title | //book/price'

选取book元素的所有title和price元素。

//title | //price

选取文档中的所有title和price元素

/bookstore/book/title | //price

选取属于bookstore元素的book元素的title元素,以及文档中的所有price元素

XPath的运算符

aabafbb640c2

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方式安装)

初步使用

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

#-*- coding:utf-8 -*-

#lxml_test.py

#使用lxml的etree库

from lxml import etree

text = '''

'''

#利用etree.HTML,将字符串解析为HTML文档

html = etree.HTML(text)

#按字符串序列化为HTML文档

result = etree.tostring(html)

print(result)

输出结果:

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

文件读取:

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

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

#lxml_parse.py

from lxml import etree

#读取外部文件hello.html

html = etree.parse('./hello.html')

result = etree.tostring(html, pretty_print=True)

print(result)

输出结果与之前相同:

XPath实例测试

1.获取所有的

标签

#xpath_li.py

from lxml import etree

html = etree.parse('hello.html')

print type(html) #显示etree.parse()返回类型

result = html.xpath('//li')

print result #打印

标签的的元素集合

print len(result)

print type(result)

print type(result[0])

输出结果:

[, , , , ]

5

2.继续获取

标签的所有class属性

#xpath_li.py

from lxml import etree

html = etree.parse('htllo.html')

result = html.xpath('//li/@class')

print result

运行结果:

['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']

3.继续获取

标签下href为link1.html的 标签

#xpath_li.py

from lxml import etree

html = etree.parse('hello.html')

result = html.xpath('//li/a[@href="link1.html"]')

print result

运行结果:

[]

4.获取

标签下的所有标签

#xpath_li.py

from lxml import etree

html = etree.parse('hello.html')

#result = html.xpath('//li/span')

#注意这么写是不对的

#因为/是用来获取子元素的,而不是的子元素,所以,要用双斜杠

result = html.xpath('//li//span')

print result

运行结果:

[]

5.获取

标签下的

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/884412
推荐阅读
相关标签
  

闽ICP备14008679号