对于Scrapy中的循环,多次返回完整响应

时间:2015-10-20 18:42:54

标签: python for-loop xpath web-scraping scrapy

我正在尝试抓一个包含电视指南的网页(带有频道和开始时间的电影)。网页的结构如下所示:

<div class="grid__col__inner">
    <div class="tv-guide__channel">
        <h6>
            <a href="./tv-gids/2be/vandaag">2BE</a>
        </h6>
    </div>
    <div class="program">
        <div class="time">22:20</div>
        <div class="title"><a href="./2be/vandaag/knowing">Knowing</a></div>
    </div>
</div>

该网页有多个grid__col__inner div。每个频道一个。每个频道可以包含多部电影。

我用Scrapy框架写了一个蜘蛛如下:

    def parse(self, response):
        for col_inner in response.xpath('//div[@class="grid__col__inner"]'):
            chnl = col_inner.xpath('//div[@class="tv-guide__channel"]/h6/a/text()').extract()
            for program in col_inner.xpath('//div[@class="program"]'):
                item = TVGuideItem()
                item['channel'] = chnl
                item['start_ts'] = program.xpath('//div[@class="time"]/text()').extract()
                item['title'] = program.xpath('//div[@class="title"]/a/text()').extract()
                yield item

因为通道名称仅在grid__col__inner div中提及一次,所以我先将其提取并将其分配给每个项目(电影)。

当我运行此代码时,它会返回每个grid__col__inner的完整结果(包含所有电影的所有通道)。下面你看到一次for循环的结果。当我运行它时,它会多次返回相同的结果。

  

{'频道':[u'VTM',                u'VITAYA”,                u'PRIME STAR',                u'PRIME ACTION',                u'PRIME FAMILY',                u'PRIME FEZZTIVAL',                u'NPO3' ],    'start_ts':[u'22:30',                 u'13:35' ,                 u'20:35' ,                 u'06:30' ,                 u'08:00' ,                 u'09:40' ,                 u'11:00' ],    'title':[u'Another 48 Hrs',              “双重比尔”,              u'Man zkt Vrouw',              u'82 dagen在4月',              u'Rio 2',              u'Epizoda u zivotu beraca zeljeza',              u'300:帝国的崛起']}

我在for循环中做错了吗?

1 个答案:

答案 0 :(得分:1)

从scrapy阅读此文档: http://doc.scrapy.org/en/latest/topics/selectors.html#working-with-relative-xpaths

当你这样做时:

chnl = col_inner.xpath('//div[@class="tv-guide__channel"]/h6/a/text()').extract()

您正在提取文档中的所有// div [@ class =“tv-guide__channel”]元素,因为//正在搜索所有文档。相反,试试这个:

chnl = col_inner.xpath('.//div[@class="tv-guide__channel"]/h6/a/text()').extract()
.//将执行相对于当前节点的搜索。 你必须对其他选择器做同样的事情:

    def parse(self, response):
    for col_inner in response.xpath('//div[@class="grid__col__inner"]'):
        chnl = col_inner.xpath('.//div[@class="tv-guide__channel"]/h6/a/text()').extract()
        for program in col_inner.xpath('.//div[@class="program"]'):
            item = TVGuideItem()
            item['channel'] = chnl
            item['start_ts'] = program.xpath('.//div[@class="time"]/text()').extract()
            item['title'] = program.xpath('.//div[@class="title"]/a/text()').extract()
            yield item

从scrapy阅读此文档: http://doc.scrapy.org/en/latest/topics/selectors.html#working-with-relative-xpaths