>>> from env_helper import info; info()
页面更新时间: 2022-03-22 11:53:28
运行环境:
Linux发行版本: Debian GNU/Linux 11 (bullseye)
操作系统内核: Linux-5.10.0-11-amd64-x86_64-with-glibc2.31
Python版本: 3.9.2
6.1. 使用 lxml 模块处理XML¶
在 Python 中常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同,使用场合也不同。 python有三种方法解析XML:SAX,DOM和ElementTree 。 但是最常用的,可能是另外一个模块: lxml 。
6.1.1. lxml 的介绍¶
lxml 是一种使用 Python 编写的库,可以迅速、灵活地处理 XML,支持 XPath。
lxml.etree和xml.etree.ElementTree两个的操作方式看起来差不多,但lxml要更好一些,使用更简洁。解析xml的时候,自动处理各种编码问题。而且它天生支持 XPath 1.0、XSLT 1.0、定制元素类。
不过,lxml不是Python自带的标准库。需要自己安装,如下方式安装:
$ pip install lxml
6.1.2. 使用 lxml¶
>>> from lxml import etree
>>>
>>> root = etree.Element('root')
>>> root.tag
'root'
>>> root.append(etree.Element('child1'))
>>> child2 = etree.SubElement(root, 'child2')
>>> child3 = etree.SubElement(root, 'child3')
>>> print(etree.tostring(root, pretty_print=True))
b'<root>n <child1/>n <child2/>n <child3/>n</root>n'
6.1.3. 元素是列表¶
为了更容易,更直接的访问这些子元素,元素尽可能地模仿 Python 列表的行为:
>>> child = root[0]
>>> child.tag
'child1'
>>> len(root)
3
>>> root.index(root[1])
1
>>> children = list(root)
>>> for child in children:
>>> print(child.tag)
child1
child2
child3
>>> etree.iselement(root)
True
>>> if len(root):
>>> print('got')
got
>>> if len(child2):
>>> print('got')
>>> child2.getparent()
<Element root at 0x7f0c5466e9c0>
>>> child2.getnext()
<Element child3 at 0x7f0c54481d80>
>>> child2.getprevious()
<Element child1 at 0x7f0c54489140>
6.1.4. 元素以属性为特征¶
XML 元素支持属性。你可以在 Element Factory直接创建它们:
>>> root = etree.Element('root', intersting = 'totally')
>>> etree.tostring(root)
b'<root intersting="totally"/>'
属性只是无序的 name-value 对,所以处理它们非常方便的方法是通过 Elements 中类似字典的界面:
>>> root.get('intersting')
'totally'
>>> root.get('Hello')
>>> root.set('Hello', 'HuHu')
>>> sorted(root.keys())
['Hello', 'intersting']
>>> for name, value in sorted(root.items()):
>>> print(f'{name}: {value}')
Hello: HuHu
intersting: totally
>>> etree.tostring(root)
b'<root intersting="totally" Hello="HuHu"/>'
>>>
>>>
>>> attributes = root.attrib
>>> attributes.get('intersting')
'totally'
6.1.5. 元素包括文本¶
元素可以包含文本:
>>> root = etree.Element('root')
>>> root.text = 'TEXT'
>>> root.text
'TEXT'
>>> etree.tostring(root)
b'<root>TEXT</root>'
>>>
>>> with open('./movie.xml') as f:
>>> # print(f.read())
>>> text = f.read()
>>> html = etree.HTML(text.encode())
>>> # print(html)
>>> print(html.tag)
>>>
>>> years = html.xpath('//year') # 从根节点向下找任意层中title的节点
>>> for year in years:
>>> print(year.tag)
>>>
>>>
>>> for tr in html.xpath('//movie[@title="Trigun"]'):
>>> print(tr)
html
year
year
<Element movie at 0x7f0c54715bc0>
可以使用 lxml 的 etree 库来进行爬取网站信息。
从豆瓣电影中提取“本周口碑榜”:
>>> import requests
>>> from lxml import etree # lxml 是c语言的库,效率非常高
>>>
>>>
>>> url = 'http://movie.douban.com'
>>> headers = {'User-agent': "Mozilla/7.0 (Windows NT 6.1) AppleWebKit/539.36 (KHTML, like Gecko) \
>>> Chrome/59.0.2883.75 Safari/537.36"}
>>> response = requests.get(url, headers=headers)
>>>
>>> with response:
>>> if response.status_code == 200:
>>> text = response.text
>>> html = etree.HTML(text)
>>> print(html.tag)
>>>
>>> titles = html.xpath('//div[@class="billboard-bd"]//a/text()')
>>> for title in titles:
>>> print(title)
>>>
>>> print("*********************")
html 青春变形记 “炼”爱 新蝙蝠侠 黑匣子 美国女孩 爱的千丝万缕 美味奇缘 沸点 杨之后 忠犬 *****************