Python xpath 无法工作?

0 投票
2 回答
2396 浏览
提问于 2025-04-15 15:09

好吧,这让我有点抓狂。我试了好几个Python的xml/xpath库,但就是找不到获取“title”元素的简单方法。

我最近的尝试是这样的(使用Amara库):

def view(req, url):
    req.content_type = 'text/plain'
    doc = amara.parse(urlopen(url))
    for node in doc.xml_xpath('//title'):
    req.write(str(node)+'\n')

但是这段代码什么都没打印出来。我的XML长这样:http://programanddesign.com/feed/atom/

如果我用//*代替//title,那就能正常返回所有内容。我知道XML里面有title,那到底是什么问题呢?是命名空间的问题吗?如果是的话,我该怎么解决?


我似乎无法在没有前缀的情况下让它工作,但这个方法是有效的:

def view(req, url):
    req.content_type = 'text/plain'
    doc = amara.parse(url, prefixes={'atom': 'http://www.w3.org/2005/Atom'})
    req.write(str(doc.xml_xpath('//atom:title')))

2 个回答

1

确实是命名空间的问题。在lxml的文档里找到这个有点棘手,不过这里是你该怎么做:

from lxml import etree
doc = etree.parse(open('index.html'))
doc.xpath('//default:title', namespaces={'default':'http://www.w3.org/2005/Atom'})

你也可以这样做:

title_finder = etree.ETXPath('//{http://www.w3.org/2005/Atom}title')
title_finder(doc)

这样做的话,无论哪种方式,你都能拿到标题。

1

你可能需要考虑一下你正在处理的文档的命名空间。

我建议你查一下如何在Amara中处理命名空间:

http://www.xml3k.org/Amara/Manual#namespaces

补充:根据你的代码片段,我做了一些修改。我不知道你使用的是哪个版本的Amara,但根据文档,我尽量做了相应的调整:

def view(req, url):
    req.content_type = 'text/plain'
    ns = {u'f' : u'http://www.w3.org/2005/Atom',
        u't' : u'http://purl.org/syndication/thread/1.0'}
    doc = amara.parse(urlopen(url), prefixes=ns)
    req.write(str(doc.xml_xpath(u'f:title')))

撰写回答