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
所以我设法写了一个蜘蛛,从这个 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