使用Scrapy XPATH获取属性名称
我正在尝试在
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有一个
(来源: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(),将函数应用于所有选定的元素节点.Scrapy选择器的一个方便的特性) 一个人想对属性节点做同样的事,对吧?但它不起作用: >>> selector.xpath('//element/@*').extract() [u'value1',u'value2'] >>> selector.xpath('//element/@*').xpath('name()').extract() [] >>> 注意:我不知道它是否是lxml / libxml2的限制,Scrapy使用它,或者如果XPath规范不允许它. (我不明白为什么会这样.) 你可以做的是使用名称(节点集)形式,即使用非空节点集作为参数.如果仔细阅读上面粘贴的XPath 1.0规范部分,与其他字符串函数一样,name(node-set)只考虑节点集中的第一个节点(按文档顺序): >>> 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,start=1): ... attribute_name = element.xpath('name(@*[%d])' % index).extract_first() ... attributes.append((attribute_name,attribute.extract())) ... >>> attributes [(u'attr1',u'attr1': u'value1'} >>> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |