gpt4 book ai didi

python - 使用 Scrapy XPATH 获取属性名称

转载 作者:太空宇宙 更新时间:2023-11-03 12:46:37 24 4
gpt4 key购买 nike

我正在尝试获取 XML 文件中某些标签属性的键和值(使用 scrapy 和 xpath)。

标签是这样的:

<element attr1="value1" attr2="value2 ...>

我不知道“attr1”、“attr2”等键,它们可以在两个元素之间变化。我没有弄清楚如何使用 xpath 获取键和值,还有其他好的做法吗?

最佳答案

精简版

>>> for element in selector.xpath('//element'):
... attributes = []
... # loop over all attribute nodes of the element
... for index, attribute in enumerate(element.xpath('@*'), start=1):
... # use XPath's name() string function on each attribute,
... # using their position
... attribute_name = element.xpath('name(@*[%d])' % index).extract_first()
... # Scrapy's extract() on an attribute returns its value
... attributes.append((attribute_name, attribute.extract()))
...
>>> attributes # list of (attribute name, attribute value) tuples
[(u'attr1', u'value1'), (u'attr2', u'value2')]
>>> dict(attributes)
{u'attr2': u'value2', u'attr1': u'value1'}
>>>

长版

XPath 有一个 name(node-set?) function获取节点名称(an attribute is a node, an attribute node):

The name function returns a string containing a QName representing the expanded-name of the node in the argument node-set that is first in document order.(...) If the argument it omitted, it defaults to a node-set with the context node as its only member.

(来源:http://www.w3.org/TR/xpath/#function-name)

>>> import scrapy
>>> selector = scrapy.Selector(text='''
... <html>
... <element attr1="value1" attr2="value2">some text</element>
... </html>''')
>>> selector.xpath('//element').xpath('name()').extract()
[u'element']

(在这里,我将 name() 链接到 //element 选择的结果,以将函数应用于所有选定的元素节点。一个方便的功能Scrapy 选择器)

有人想对属性节点做同样的事情,对吧?但它不起作用:

>>> selector.xpath('//element/@*').extract()
[u'value1', u'value2']
>>> selector.xpath('//element/@*').xpath('name()').extract()
[]
>>>

注意:我不知道这是 lxml/libxml2 的限制,Scrapy 在后台使用它,还是 XPath 规范不允许它。 (我不明白为什么会这样。)

不过,您可以做的是使用 name(node-set) 形式,即使用非空节点集作为参数。如果您仔细阅读我上面粘贴的 XPath 1.0 规范部分,与其他字符串函数一样,name(node-set) 仅考虑 first node节点集(按文档顺序):

>>> selector.xpath('//element').xpath('@*').extract()
[u'value1', u'value2']
>>> selector.xpath('//element').xpath('name(@*)').extract()
[u'attr1']
>>>

属性节点也有位置,因此您可以按位置遍历所有属性。这里我们有 2(上下文节点上 count(@*) 的结果):

>>> for element in selector.xpath('//element'):
... print element.xpath('count(@*)').extract_first()
...
2.0
>>> for element in selector.xpath('//element'):
... for i in range(1, 2+1):
... print element.xpath('@*[%d]' % i).extract_first()
...
value1
value2
>>>

现在,您可以猜出我们可以做什么:为每个 @*[i]

调用 name()
>>> for element in selector.xpath('//element'):
... for i in range(1, 2+1):
... print element.xpath('name(@*[%d])' % i).extract_first()
...
attr1
attr2
>>>

如果将所有这些放在一起,并假设 @* 将按文档顺序获取属性(我认为在 XPath 1.0 规范中没有说明,但这是我在 中看到的情况lxml),你最终会得到这个:

>>> attributes = []
>>> for element in selector.xpath('//element'):
... for index, attribute in enumerate(element.xpath('@*'), start=1):
... attribute_name = element.xpath('name(@*[%d])' % index).extract_first()
... attributes.append((attribute_name, attribute.extract()))
...
>>> attributes
[(u'attr1', u'value1'), (u'attr2', u'value2')]
>>> dict(attributes)
{u'attr2': u'value2', u'attr1': u'value1'}
>>>

关于python - 使用 Scrapy XPATH 获取属性名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32790549/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com