什么是 XML
XML 指可扩展标记语言 (EXtensible Markup Language)
XML 是一种标记语言, 很类似 html
XML 的设计宗旨是传输数据, 而非显示数据
XML 的标签需要我们自行定义.
XML 被设计为具有自我描述性.
XML 是 W3C 的推荐标准
W3School 官方文档: http://www.w3school.com.cn/xml/index.asp
XML 和 HTML 的区别:
数据格式 | 描述 | 设计目标 |
---|---|---|
XML | Extensible Markup Language (可扩展标记语言) | 被设计为传输和存储数据, 其焦点是数据的内容. |
HTML | HyperText Markup Language (超文本标记语言) | 显示数据以及如何更好显示数据. |
HTML DOM | Document Object Model for HTML (文档对象模型) | 通过 HTML DOM, 可以访问所有的 HTML 元素, 连同它们所包含的文本和属性. 可以对其中的内容进行修改和删除, 同时也可以创建新的元素. |
什么是 XPath?
??XPath (XML Path Language) 是一门在 XML 文档中查找信息的语言, 可用来在 XML 文档中对元素和属性进行遍历.
W3School 官方文档: http://www.w3school.com.cn/xpath/index.asp
XPath 开发工具
开源的 XPath 表达式编辑工具: XMLQuire(XML 格式文件可用)
Chrome 插件 XPath Helper
Firefox 插件 try XPath
语法
??XPath 使用路径表达式来选取 XML 文档中的节点或者节点集. 这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似.
选取节点
下面列出了最常用的路径表达式:
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点 |
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档中的节点, 而不考虑它们的位置. |
. | 选取当前节点. |
.. | 选取当前节点的父节点. |
@ | 选取属性. |
谓语 (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() | 匹配任何类型的节点. |
选取若干路径
通过在路径表达式中使用 "|" 运算符, 您可以选取若干个路径.
路径表达式 | 结果 |
---|---|
//book/title | //book/price | 选取 book 元素的所有 title 和 price 元素. |
//title | //price | 选取文档中的所有 title 和 price 元素. |
/bookstore/book/title | //price | 选取属于 bookstore 元素的 book 元素的所有 title 元素, 以及文档中所有的 price 元素. |
这些就是 XPath 的语法内容, 在运用到 Python 抓取时要先转换为 xml.
lxml 库
??lxml 是 一个 HTML/XML 的解析器, 主要的功能是如何解析和提取 HTML/XML 数据.
??lxml 和正则一样, 也是用 C 实现的, 是一款高性能的 Python HTML/XML 解析器, 我们可以利用之前学习的 XPath 语法, 来快速的定位特定元素以及节点信息.
??lxml python 官方文档: http://lxml.de/index.html
?? 需要安装 C 语言库, 可使用 pip 安装: pip3 install lxml (或通过 wheel 方式安装)
解析 HTML 代码
- # 使用 lxml 的 etree 库
- from lxml import etree
- text = '''
- <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 文档, 返回类型:<class'lxml.etree._ElementTree'>
- html = etree.HTML(text)
- # 按字符串序列化 HTML 文档
- result = etree.tostring(html).decode("utf-8")
- print(result)
lxml 可以自动修正 html 代码, 例子里不仅补全了 li 标签, 还添加了 body,html 标签.
文件读取
除了直接读取字符串, lxml 还支持从文件里读取内容. 新建一个 html 文件, 再利用 etree.parse() 方法来读取文件.
- from lxml import etree
- # 读取外部文件, 返回类型:<class 'lxml.etree._ElementTree'>
- html = etree.parse('./hello.html')
- result = etree.tostring(html, pretty_print=True)
- print(result)
XPath 实例
1 获取所有的 <li> 标签
- from lxml import etree
- html = 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]))
2 获取 < li > 标签的所有 class 属性
- html = etree.parse('hello.html')
- result = html.xpath('//li/@class')
3 获取 < li > 标签下的所有 <span> 标签
- # 因为 / 是用来获取子元素的, 而 <span> 并不是 <li> 的子元素, 所以, 要用双斜杠
- result = html.xpath('//li//span')
4 获取 class 值为 bold 的标签名
- result = html.xpath('//*[@class="bold"]')
- # tag 方法可以获取标签名
- print result[0].tag
来源: http://www.bubuko.com/infodetail-2768492.html