【问题标题】:Python - use lxml to return value of title.text attribPython - 使用 lxml 返回 title.text 属性的值
【发布时间】:2012-11-28 15:37:17
【问题描述】:

我试图弄清楚如何使用 lxml 从 url 解析 xml 以返回 title 属性的值。有谁知道我有什么问题或什么会返回标题值/文本?所以在下面的例子中,我想返回'Weeds - S05E05 - Van Nuys - HD TV'的值

来自 URL 的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0">
<song id="11345" parent="11287" title="Weeds - S05E05 - Van Nuys - HD TV" album="Season 5" artist="Weeds" isDir="false" created="2009-07-06T22:21:16" duration="1638" bitRate="384" size="782304110" suffix="mkv" contentType="video/x-matroska" isVideo="true" path="Weeds/Season 5/Weeds - S05E05 - Van Nuys - HD TV.mkv" transcodedSuffix="flv" transcodedContentType="video/x-flv"/>
</subsonic-response>

我当前的 Python 代码:

import lxml
from lxml import html
from urllib2 import urlopen

url = 'https://myurl.com'

tree = html.parse(urlopen(url))
songs = tree.findall('{*}song')
for song in songs:
    print song.attrib['title']

使用上面的代码,我没有得到任何数据返回,有什么想法吗?

打印出树 =

<lxml.etree._ElementTree object at 0x0000000003348F48>

打印出歌曲 =

[]

【问题讨论】:

  • 您没有使用lxml 功能。只有标准库 ElementTree 实现实际上在您的示例中起作用。 import lxml.html as lh 可以安全地从代码中删除。
  • 我已经尝试过使用内置的 ElementTree,但也无法让它工作,所以我想我会尝试 lxml。只是不知道如何编写正确的代码。

标签: python parsing lxml


【解决方案1】:

首先,您实际上并没有在代码中使用lxml。您导入了lxml HTML 解析器,否则忽略它,而只使用标准库xml.etree.ElementTree module

其次,您搜索data/song,但您的文档中没有任何data 元素,因此找不到匹配项。最后但并非最不重要的一点是,您有一个使用名称空间的文档。您必须在搜索元素时包含这些元素,或使用{*} 通配符搜索。

以下为您查找歌曲:

from lxml import etree

tree = etree.parse(URL)  # lxml can load URLs for you
songs = tree.findall('{*}song')
for song in songs:
    print song.attrib['title']

要使用显式命名空间,您必须将 {*} 通配符替换为完整的命名空间 URL;默认命名空间在 tree 对象上的 .nsmap 命名空间字典中可用:

namespace = tree.nsmap[None]
songs = tree.findall('{%s}song' % namespace)

【讨论】:

  • import lxml from lxml import etree url = 'https://myurl.com' tree = lxml.parse(url) # lxml can load URLs for you songs = tree.findall('{*}song') for song in songs: print song.attrib['title'] 出现错误:AttributeError: 'module' object has no attribute 'parse'
  • 出现错误:` tree = etree.parse(url) 文件“parser.pxi”,第 1002 行,在 lxml.etree._BaseParser._parseDocFromFile (src/lxml\lxml.etree.c:78623 ) 文件“parser.pxi”,第 569 行,在 lxml.etree._ParserContext._handleParseResultDoc (src/lxml\lxml.etree.c:74567) 文件“parser.pxi”,第 650 行,在 lxml.etree._handleParseResult (src /lxml\lxml.etree.c:75458) 文件“parser.pxi”,第 588 行,在 lxml.etree._raiseParseError (src/lxml\lxml.etree.c:74760) IOError: 读取文件时出错'myurl.com' : 未能加载外部实体“myurl.com”`
  • 抱歉编辑了它以适应评论,但是我的网址是 https,这有关系吗?
  • @nutt318:是的,https 显然不受支持,对此感到抱歉。见What is the deal about https when using lxml?
  • 我已经在上面的例子中更新了我的代码,现在我没有任何回报。有什么想法吗?
【解决方案2】:

整个问题在于subsonic-response 标记具有xmlns 属性,表明存在有效的xml 命名空间。下面的代码考虑到了这一点,并正确地添加了歌曲标签。

import xml.etree.ElementTree as ET
root = ET.parse('test.xml').getroot()
print root.findall('{http://subsonic.org/restapi}song')

【讨论】:

    【解决方案3】:

    感谢大家的帮助,我结合使用了你们的两个来让它工作。

    import xml.etree.ElementTree as ET
    from urllib2 import urlopen
    
    url = 'https://myurl.com'
    root = ET.parse(urlopen(url)).getroot()
    for song in root:
        print song.attrib['title']
    

    【讨论】:

    • 但是,当我将它放入一个变量中时,它会删除空格,关于如何保留空格的任何想法?
    猜你喜欢
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    • 2017-07-13
    • 1970-01-01
    相关资源
    最近更新 更多