Python scrapy - 产生初始项目和从回调到 csv 的项目

Python scrapy - yield initial items and items from callback to csv

所以我设法写了一个蜘蛛,从这个 site 中提取 "Videos" 和 "English Transcripts" 的下载链接。查看 cmd window 我可以看到所有正确的信息都已被抓取。

我遇到的问题是输出的 csv 文件只包含 "Video" 链接而不包含 "English Transcripts" 链接(即使您可以看到它已在 cmd window).

我已经尝试了其他帖子中的一些建议,但其中 none 似乎有效。

下图是我希望输出的样子: CSV Output Picture

这是我当前的蜘蛛代码:

import scrapy

class SuhbaSpider(scrapy.Spider):
    name = "suhba2"
    start_urls = ["http://saltanat.org/videos.php?topic=SheikhBahauddin&gopage={numb}".format(numb=numb)
        for numb in range(1,3)]

    def parse(self, response):
        yield{
            "video" : response.xpath("//span[@class='download make-cursor']/a/@href").extract(),
        }
        fullvideoid = response.xpath("//span[@class='media-info make-cursor']/@onclick").extract()

        for videoid in fullvideoid:
            url = ("http://saltanat.org/ajax_transcription.php?vid=" + videoid[21:-2])
            yield scrapy.Request(url, callback=self.parse_transcript)

    def parse_transcript(self, response):
        yield{
            "transcript" : response.xpath("//a[contains(@href,'english')]/@href").extract(),
        }

您正在生成两种不同的项目 - 一种仅包含 video 属性,另一种仅包含 transcript 属性。您必须产生一种由两种属性组成的项目。为此,您必须在 parse 中创建项目并使用 meta 将其传递给二级请求。然后,在 parse_transcript 中,您从 meta 中获取它,填充其他数据并最终生成该项目。 Scrapy documentation.

中描述了一般模式

第二件事是使用 extract() 方法一次提取所有视频。这会产生一个列表,其中很难 link 每个单独的元素都有相应的转录本。更好的方法是遍历 HTML 中的每个视频元素并为每个视频生成项目。

应用于您的示例:

import scrapy

class SuhbaSpider(scrapy.Spider):
    name = "suhba2"
    start_urls = ["http://saltanat.org/videos.php?topic=SheikhBahauddin&gopage={numb}".format(numb=numb) for numb in range(1,3)]

    def parse(self, response):
        for video in response.xpath("//tr[@class='video-doclet-row']"):
            item = dict()
            item["video"] = video.xpath(".//span[@class='download make-cursor']/a/@href").extract_first()

            videoid = video.xpath(".//span[@class='media-info make-cursor']/@onclick").extract_first()
            url = "http://saltanat.org/ajax_transcription.php?vid=" + videoid[21:-2]
            request = scrapy.Request(url, callback=self.parse_transcript)
            request.meta['item'] = item
            yield request

    def parse_transcript(self, response):
        item = response.meta['item']
        item["transcript"] = response.xpath("//a[contains(@href,'english')]/@href").extract_first()
        yield item