我试图让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.Request
或response.follow_all
的变量在运行时包含一个链接或一个链接列表。到达我期望开始抓取链接的行,但parse
或parse_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
时看到的。