前言
lxml是一个非常强大的解析库,支持解析多种格式数据。比较常见的是html和xml.
因为接触解析xml工作比较少, 所以在解析中遇到了很多的问题, 希望通过这边文章记录并分享,本篇文章仅供参考,欢迎大家给予建议。
1. 普通xml(无命名空间,命名空间就是xml标签中带冒号的数据)可以选择使用html进行解析
from lxml import etree
def parse_xml(xml_data):
# html 默认使用的parser 位 HTMLParser, 下面两行注释代码与下方代码功能一致
# parser = etree.HTMLParser(encoding='utf-8')
# html = etree.HTML(xml_data.encode('utf-8'), parser=parser)
html = etree.HTML(xml_data.encode('utf-8'))
title = html.xpath('//feed/entry/title/text()')
print('title:', title)
2. xml(带命名空间,命名空间就是xml标签中带冒号的数据)可以选择使用xml进行解析
from lxml import etree
name_spaces = {
'media': 'http://search.yahoo.com/mrss/',
}
def parse_xml(xml_data):
# html 默认使用的parser 位 HTMLParser, 下面两行注释代码与下方代码功能一致
# parser = etree.XMLParser(encoding='utf-8')
# html = etree.XML(xml_data.encode('utf-8'), parser=parser)
xml = etree.XML(xml_data.encode('utf-8'))
title = xml.xpath('//media:group/media:title/text()', namespaces=name_spaces)
print('title:', title)
上面两种方式是无法同时使用xpath解析出来即包含命名空间的标签和不包含命名空间的标签。
3. 最终解析示例如下:
name_spaces = {
'yt': 'http://www.youtube.com/xml/schemas/2015',
}
def parse_xml(xml_data):
xml = etree.XML(data.encode('utf-8'))
for child in xml:
if child.tag.find('entry') != -1:
entry = child
# 解析命名空间数据
message_id = entry.xpath('./yt:videoId/text()', namespaces=name_spaces)
user_id = entry.xpath('./yt:channelId/text()', namespaces=name_spaces)
# 解析非命名空间数据
for entry_child in entry:
if entry_child.tag.find('link') != -1:
url = entry_child.attrib.get('href', '')
elif entry_child.tag.find('published') != -1:
publish_date = entry_child.text