代码之家  ›  专栏  ›  技术社区  ›  fg42

正确安排两个for循环的结果

  •  3
  • fg42  · 技术社区  · 6 年前

    从下面的代码中可以看到,我正在用Scrapy刮取一些信息。一切都很好,我只是对存储刮取的数据的方式不满意。对于当前代码,我将结果作为“X”列和“Y”列并排显示(这很好),但“U”的结果显示为一行,因为它是从第二个循环运行的。所以,我想要的是,将刮取的数据并排放在三列中:X/Y/U。有人能帮忙吗?提前感谢!

    def parse(self, response):
        U = []
        for l in response.css('div.property-info-wrapper'):
            yield {
                'X': l.css('span.info-price::text').extract_first(),
                'Y': l.css('li::text').extract_first(),
            }
    
        for i in response.selector.xpath('//div[@class="property-info-location ellipsis-element-control"]/text()').extract():
            U.append(i)
        yield {'U':U}
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Mazdak    6 年前

    您可以使用 itertools.zip_longest 将两个结果压缩在一起,并根据它们的真值生成它们 *

    from itertools import zip_longest
    
    def parse(self, response):
        locations = response.selector.xpath('//div[@class="property-info-location ellipsis-element-control"]/text()').extract()
        css = response.css('div.property-info-wrapper')
    
        for loc, c in zip_longest(css, locations):
            if loc:
                yield {
                    'X': loc.css('span.info-price::text').extract_first(),
                    'Y': loc.css('li::text').extract_first(),
                }
            if c:
                yield {'U': c}  # since spider needs to return dict
    

    * itertools.zip_longest(*iterables, fillvalue=None) : 制作一个迭代器,聚合来自每个iterables的元素。如果iterables的长度不均匀,则缺少的值将用fillvalue填充。迭代将继续,直到最长的iterable耗尽。