【问题标题】:Python scrapy - yield initial items and items from callback to csvPython scrapy - 从回调到csv产生初始项目和项目
【发布时间】:2017-10-20 16:10:42
【问题描述】:

所以我设法编写了一个爬虫,从这个site 中提取“视频”和“英语成绩单”的下载链接。查看 cmd 窗口,我可以看到所有正确的信息都已被抓取。

我遇到的问题是输出的 csv 文件只包含“视频”链接而不是“英语成绩单”链接(即使您可以在 cmd 窗口中看到它已被抓取)。

我尝试了其他帖子中的一些建议,但似乎都没有奏效。

下图是我希望输出的样子: 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(),
        }

【问题讨论】:

标签: python-2.7 scrapy export-to-csv scrapy-spider


【解决方案1】:

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

第二件事是您使用extract() 方法一次提取所有视频。这会产生一个列表,之后很难将每个单独的元素与相应的成绩单链接起来。更好的方法是循环遍历 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

【讨论】:

  • 这将是可疑的,因为会向ajax_transcription.php 请求没有转录的视频。重要的是,您的 Spider 的行为与网站的行为完全相同。也就是说,您必须通过选择器检查转录是否存在,并且只向拥有它们的人发出请求。
  • 另外,我建议添加 X-Requested-With 标头和 XMLHttpRequest。同样的原因。
  • 我试图提供一个应用主要思想的示例,而不是提供可立即运行的代码。检查站点细节取决于 OP。
  • @TomášLinhart 感谢一百万的解释和解决方案,它完美运行!
  • @AndrésPérez-AlbelaH。感谢您的建议,我没有想到这些,一定会添加它们
猜你喜欢
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 2019-07-26
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 2019-02-18
相关资源
最近更新 更多