doc = Nokogiri::XML(open("http://api.chartlyrics.com/apiv1.asmx//GetLyric?lyricId=90&lyricCheckSum=9600c891e35f602eb6e1605fb7b5229e"))
成功获取文档内容。
在此之后我无法进入并抓取数据,我不知道为什么?
例如,我希望:
doc.xpath("//LyricArtist")
要反击艺术家,但事实并非如此。
我尝试过与其他Feed相同的内容,例如任何wordpress安装提供的默认RSS Feed,如果我执行类似的操作:
doc.xpath("//link")
我得到了所有“链接”的列表。
我肯定错过了一些东西,并且非常喜欢你的意见。谢谢!!
答案 0 :(得分:3)
XML元素是名称空间限定的并绑定到http://api.chartlyrics.com/
。
如果您查看XML,您会注意到document元素有一个名称空间decalred:
<GetLyricResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://api.chartlyrics.com/">
为了匹配绑定到命名空间的元素,您需要声明绑定到该URI的命名空间前缀并在XPATH表达式中使用该命名空间前缀,或者使用忽略命名空间的XPATH表达式或匹配不同。
您可以匹配元素,然后使用local-name()
匹配元素名称,无论声明的名称空间如何。
//*[local-name()='LyricArtist']
如果您想更精确,可以使用local-name()
匹配元素名称和namespace-uri()
以匹配声明的命名空间。
//*[local-name()='LyricArtist' and namespace-uri()='http://api.chartlyrics.com/']
第二个示例将阻止匹配具有绑定到不同命名空间的相同local-name()
的元素。对于这个特定的实例,可能不是问题,但是你应该注意这一点。命名空间用于唯一限定节点,并允许不同的词汇表使用相同的“名称”,而不必担心冲突。
答案 1 :(得分:0)
它不喜欢命名空间或架构中的某些内容。
uri = "http://api.chartlyrics.com/apiv1.asmx//GetLyric?LyricId=90&lyricCheckSum=9600c891e35f602eb6e1605fb7b5229e"
x = open(uri).read()
x = x.sub(/<.*?>/,'').sub(/<.*?>/,'<GetLyricResult>')
doc = Nokogiri::XML(x)
puts doc.xpath('//LyricArtist').text()