试图发送一个抓取器来抓取从第一个目的地抓取的一批链接(递归抓取).怎么做呢?



我试图让Scrapy跟随一些我已经成功从一个页面上抓取的链接。

我看到有两种方法被描述过,但都不适合我。

选项1

第一个来自Scrapy教程。Ctrl + fyield scrapy.Request(next_page, callback=self.parse)找到我要找的部分。这是我试图模仿它:

import scrapy
import logging
logging.getLogger('scrapy').propagate = False
class SomeSpider(scrapy.Spider):
name = "someSpider"
allowed_domains = ["someplace.com/"]
start_urls = [
"https://someplace.com/AU/"
]
def parse(self, response, y=False, x=False):
if not x:
links_to_follow = response.css('a::attr(href)').getall()
for link in links_to_follow:
print(link)  # I've cut out some code, but this is always a URL, like www.google.ca
scrapy.Request(link, callback=self.parse(x=True))
else:
print("you are here")

"you are here"声明从未达成。我得到一个错误,但似乎这是一个完全糟糕的方法:我宁愿有一个单独的解析函数的链接,我下面,因为我正在解析的页面是不同的字符从主页。

选项2

然后有一个选项,基本上是"为你正在抓取的链接编写一个特定的解析函数";从StackOverflow线程标题为"解析提取链接与另一个函数"它使用response.follow_all()

当我这样做的时候是什么样子的:

def parse(self, response, y=False, x=False):
links_to_follow = response.css('a::attr(href)').getall()
for link in links_to_follow:
print(link)  # I've cut out some code, but this is always a URL, like www.google.ca
response.follow_all(links_to_follow, self.parse_products)

def parse_products(self, response):
print("you are here")

没有"你在这里"。

选项3

在寻找如何将参数传递给回调函数时,我发现了第三种假设的解决方案。我的尝试:

def parse(self, response, y=False, x=False):
links_to_follow = response.css('a::attr(href)').getall()
for link in links_to_follow:
print(link)  # I've cut out some code, but this is always a URL, like www.google.ca
scrapy.Request(link, callback=self.parse_products, meta={"x":True})
def parse_products(self, response):
print("you are here")

没有"你在这里"。

如果我能到达"你在这里"与response参数一起从页面中通过数据,就像在开始parse方法中一样,我将能够从那里取走它。我只是没有把那行打印成我期望的样子。

一个脚注:我在没有测试删节后的版本是否可以运行的情况下删除了很多代码。但是我保证,在我所有的代码中,我插入到scrapy.Requestresponse.follow_all的变量在运行时包含一个链接或一个链接列表。到达我期望开始抓取链接的行,但parseparse_products位没有执行。

您可以通过从一开始就使用meta来简化它

def parse(self, response):
x = response.meta.get('x', False)
y = response.meta.get('y', False)
if not x:
links_to_follow = response.css('a::attr(href)').getall()
for link in links_to_follow:
print link  # I've cut out some code, but this is always a URL, like www.google.ca
yield scrapy.Request(link, callback=self.parse, meta={'x': True})
else:
print 'you are here'

还要确保从爬虫中删除allowed_domains,因为这是一个开放的爬虫,从一开始就不知道域名

最后,我错过的是……

(1)当我在测试中运行scrapy.Request(link, callback=self.parse_products)时,我的parse_products方法缺少了关键的一行。请看这里的注释行:

def parse_products(self, response):
print("you are here")
divs = response.css("div.product-tile > div::attr(class)").getall()
yield divs  # "yield divs" was necessary to make the code output what I wanted.

(2)我不得不把dont_filter旗作为True,正如Tarun Lalwani在他的帖子中所说的。

我不明白为什么Scrapy如此热衷于yield。这与程序处理大数据的方式有关吗?这是我在研究yield时看到的。