在多个CSV行之间拆分Scrapy元素

时间:2018-04-24 07:22:45

标签: python csv scrapy scrapy-spider

我一直在做一些我认为应该相对容易的事情,但是我一直在撞墙。我已经尝试过stackoverflow中的多个类似解决方案,并且我已经改进了我的代码,但仍然坚持基本功能。

我正在抓取一个网页,该网页返回一个必不可少的流派元素(流派):

Mystery, Comedy, Horror, Drama

xpath完美返回。我使用Scrapy管道输出到CSV文件。我想要做的是为上面列表中的每个项目创建一个单独的行以及页面网址:

"Mystery", "http:domain.com/page1.html"
"Comedy", "http:domain.com/page1.html"

无论我尝试什么,我都只能输出:

"Mystery, Comedy, Horror, Drama", ""http:domain.com/page1.html"

这是我的代码:

def parse_genre (self, response):
    for item in [i.split (',') for i in response.xpath ('//span [contains (@class, "genre")]/text()').extract()]:
        sg = ItemLoader (item=ItemGenre (), response=response)
        sg.add_value ('url', response.url)
        sg.add_value ('genre', item, MapCompose(str.strip))
        yield sg.load_item ()

这是从蜘蛛的主解析程序中调用的。这一切都正常运作。 (我在每个网页上都有两个项目。主蜘蛛收集了父母的信息,这个功能正在尝试收集儿童信息。技术上不是儿童记录,但绝对是1对多的关系。)

我尝试了许多可能的解决方案。这是唯一对我有意义的版本,看起来应该可行。我确定我没有正确分割流派字符串。

1 个答案:

答案 0 :(得分:0)

你非常接近。 你的罪魁祸首似乎是你获得物品的方式:

items = response.xpath('//span[contains (@class, "genre")]/text()').extract()]
for item in items:
    for category in item.split(','):
        sg = ItemLoader(item=ItemGenre(), response=response)
        sg.add_value('url', response.url)
        sg.add_value('genre', category, MapCompose(str.strip))
        yield sg.load_item ()

如果没有源代码,我无法完全纠正你,但很明显,你的代码会返回一个列表列表。

您应该将此列表列表展平为字符串列表或适当地迭代它:

items = response.xpath('//span[contains (@class, "genre")]/text()').extract()]
# good cheatsheet to remember this [leaf for tree in forest for leaf in tree]
categories = [cat for item in items for cat in items]
for category in categories:
    sg = ItemLoader(item=ItemGenre(), response=response)
    sg.add_value('url', response.url)
    sg.add_value('genre', category, MapCompose(str.strip))
    yield sg.load_item ()

替代更多先进技术将使用列表嵌套理解:

newStudents