使用text(),有没有办法用scrapy将空文本转换为'None'

时间:2013-04-05 19:37:48

标签: python xml xpath web-scraping scrapy

我遇到了问题。我正在抓取的网站xml有一些空的值,但我需要保留值的顺序。

样品:

<thedata>
    <some-item>
        <value xsi:nil="true"/>
        <value xsi:nil="true"/>
        <value xsi:nil="true"/>
        <value xsi:nil="true"/>
        <value xsi:nil="true"/>
        <value>44</value>
        <value>32</value>
        <value>31</value>
        <value xsi:nil="true"/>
        <value xsi:nil="true"/>
        <value>32</value>
        <value>31</value>
        <value>34</value>
        <value>34</value>
        <value>33</value>
    </some-item>
</thedata>

执行text()会忽略空值:

class MySpider(XMLFeedSpider):
    name = 'myspider'
    start_urls = ['http://www.example.com/somexml.xml']
    itertag = 'thedata'

    # Using XMLFeedSpider
    def parse_node(self, response, node):
        item_vals = node.select('some-item/value/text()').extract()
        print item_vals

这将打印一个列表,其中只包含具有整数的值。

由于我需要保留订单,有没有办法告诉scrapy用''None替换任何空值?

修改: @unutbu:我仍然遇到同样的问题:

    item_vals = node.select('some-item/value/text()').extract()
    print item_vals
    item_vals2 = node.select('some-item/value/text()').extract() or None
    print item_vals2

输出:

    [u'44',u'32',u'31',u'32',u'31',u'34',u'34',u'33']
    [u'44',u'32',u'31',u'32',u'31',u'34',u'34',u'33']

我想要的是:

    [None,None,None,None,None,u'44',u'32',u'31',None,None,u'32',u'31',u'34',u'34',u'33']

或者在遇到空值时表示空值。

2 个答案:

答案 0 :(得分:4)

您需要选择所有值节点,然后从每个部分中提取文本(如果有):

[txt for item in hxs.select('some-item/value') for txt in item.select('text()').extract() or [u'']]

答案 1 :(得分:0)

您可以使用Becker方法实现此目的:

>>> from scrapy.selector import XmlXPathSelector
>>> xml = """<thedata>
...     <some-item>
...         <value xsi:nil="true"/>
...         <value xsi:nil="true"/>
...         <value xsi:nil="true"/>
...         <value xsi:nil="true"/>
...         <value xsi:nil="true"/>
...         <value>44</value>
...         <value>32</value>
...         <value>31</value>
...         <value xsi:nil="true"/>
...         <value xsi:nil="true"/>
...         <value>32</value>
...         <value>31</value>
...         <value>34</value>
...         <value>34</value>
...         <value>33</value>
...     </some-item>
... </thedata>
... """
>>> xxs = XmlXPathSelector(text=xml)
>>> thedata = xxs.select('some-item/value').select(
... 'concat('
... ' substring(text(), 1, number(text()) * string-length(text())),'
... ' substring("nil", 1, number(not(text())) * string-length("nil")))'
... ).extract()
>>> thedata
[u'nil', u'nil', u'nil', u'nil', u'nil', u'44', u'32', u'31', u'nil', u'nil', u'32', u'31', u'34', u'34', u'33']

如果您想获得None值:

>>> map(lambda v: None if v == 'nil' else v, thedata)
[None, None, None, None, None, u'44', u'32', u'31', None, None, u'32', u'31', u'34', u'34', u'33']