全栈工程师开发手册 (作者:栾鹏)
python教程全解
python网络爬虫lxml库的应用全解。
在线安装方法:cmd中输入"pip install lxml"
离线安装,下载lxml库点击下载
python库的安装请参考Python库的安装与卸载
xpath路径选择表达式
lxml库需要记住的主要是路径选择表达式。
语法规则
表达式 描述
nodename 选取此节点的所有子节点。
/ 子元素。
// 后代元素。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性(获取属性的值)。
举例:
路径表达式 结果
bookstore 选取 bookstore 元素的所有子节点。
/bookstore 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。
//book 选取所有 book 后代元素,而不管它们在文档中的位置。
bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang 选取名为 lang 的所有属性(获取所有名为lang属性的值)。
谓语举例:
路径表达式 结果
/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。
通配符:
通配符 描述
* 匹配任何元素节点。
@* 匹配任何属性节点。
node() 匹配任何类型的节点。
通配符举例:
路径表达式 结果
/bookstore/* 选取 bookstore 元素的所有子元素。
//* 选取文档中的所有元素。
//title[@*] 选取所有带有属性的 title 元素。
|或运算符举例:
路径表达式 结果
//book/title | //book/price 选取 book 元素的所有 title 和 price 元素。
//title | //price 选取文档中的所有 title 和 price 元素。
/bookstore/book/title | //price 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。
python2.7、python3.6中代码
# coding:utf-8
# 网络爬虫库lxml的应用
from lxml import etree
print(u'解析html(具有自动修复功能)')
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"><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>
</ul>
</div>
'''
html = etree.HTML(text)
result = etree.tostring(html)
print(result)
# 将字符串写入文件
fh = open('test.html', 'w')
fh.write(result.decode("utf8")) #fh.write(result)
fh.close()
print(u'读取文件(要求html代码完整)')
html = etree.parse('test.html') #只能解析本地html、xml文件
result = etree.tostring(html, pretty_print=True)
print(result)
print(u'获取所有的 <li> 标签')
html = etree.parse('test.html') # 创建dom树
print(type(html))
result = html.xpath('//li') # 获取元素列表
print(result)
print(len(result)) # 获取列表长度
print(type(result))
print(type(result[0])) # 获取元素
result = html.xpath('//li/@class') # 获取 <li> 标签的所有 class属性的值
print(result)
result = html.xpath('//li/a[@href="link1.html"]') # 获取 <li> 标签下 href 为 link1.html 的 <a> 标签
print(result)
result = html.xpath('//li//span') # 获取 <li> 标签下的所有后代元素 <span> 标签
print(result)
result = html.xpath('//li/span') # 获取 <li> 标签下的所有子元素 <a> 标签
print(result)
result = html.xpath('//li/a//@class') # 获取 <li> 标签下的所有a元素的后代 class
print(result)
result = html.xpath('//li[last()]/a/@href') # 获取最后一个 <li> 下的 <a> 的 href属性
print(result)
result = html.xpath('//li[last()-1]/a') # 获取倒数第二个li元素下的a元素列表
print(result[0].text) # 打印输出元素文本
result = html.xpath('//*[@class="bold"]') # 获取 class 为 bold 的标签名
print(result[0].tag)