在 Python 中常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同,使用场合也不同。
Python有三种方法解析XML:SAX,DOM和ElementTree。 但是最常用的,可能是另外一个模块: lxml
。
# pip install 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'
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 0x7f7b71fcac00>
child2.getnext()
<Element child3 at 0x7f7b71fb1780>
child2.getprevious()
<Element child1 at 0x7f7b71f2a040>
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'
元素可以包含文本:
root = etree.Element('root')
root.text = 'TEXT'
root.text
'TEXT'
etree.tostring(root)
b'<root>TEXT</root>'
with open('/data/demo/movie.xml') as f:
# print(f.read())
text = f.read()
html = etree.HTML(text.encode())
# print(html)
print(html.tag)
html
从根节点向下找任意层中title的节点。
years = html.xpath('//year')
for year in years:
print(year.tag)
year year
for tr in html.xpath('//movie[@title="Trigun"]'):
print(tr)
<Element movie at 0x7f7b71ff0440>
可以使用 lxml
的 etree
库来进行爬取网站信息。
从豆瓣电影中提取“本周口碑榜”:
import requests
lxml 是c语言的库,效率非常高。
from lxml import etree
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 孤独摇滚(上) 孤独的美食家 剧场版 黎明的一切 爱的暂停键 共同的语言 最后的里程 大风杀 雷霆特攻队* 新干线惊爆倒数 女儿的女儿 *********************