想象一下,我正在抓取foo.com
。 foo.com有几个内部链接,它有一些外部链接,如:
foo.com/hello
foo.com/contact
bar.com
holla.com
我希望scrapy能够抓取所有内部链接,但也只有一个深度用于外部链接,例如我希望scrapy转到bar.com
或holla.com
,但我不希望它转到任何其他链接在bar.com
内,所以只有一个深度。
感谢。
答案 0 :(得分:1)
您可以将蜘蛛基于CrawlSpider
课程,并使用已实施Rule
方法的process_links
,并将其传递给Rule
。该方法将在跟踪之前过滤不需要的链接。来自documentation:
process_links
是一个可调用的或一个字符串(在这种情况下,将使用来自具有该名称的蜘蛛对象的方法),将使用指定的{{从每个响应中提取的每个链接列表调用该字符串。 1}}。这主要用于过滤目的。
答案 1 :(得分:0)
不是内置解决方案,但我相信您必须自己中断递归。你可以通过在蜘蛛中保留一组(一组)域并中断或忽略来轻松实现这一点。
某种东西:
from urllib.parse import urlparse
self.track = set()
...
domain = tracktraurlparse(response.url).netloc
x.add(domain)
if len(x) > MAX_RECURSION:
x.remove(domain)
# raise StopIteration (# if you're within a generator)
return None
答案 2 :(得分:0)
我通过将参数传递给回调函数找到了解决方案。如果url是内部链接,我将flag设置为true(否则为false)。如果flag返回false(外部链接),则爬网程序不会提取新链接。这是我的示例代码:
class BrokenLinksSpider(CrawlSpider):
name = test
start_urls = "your_url"
def parse(self, response):
flag = response.meta.get('flag')
if flag or flag==None:
extractor = LinkExtractor(deny_domains="")
links = extractor.extract_links(response)
for link in links:
if link.url[:8]=="your_url":
new_request = Request(link.url, callback=self.parse,meta={'flag': True})
else:
new_request = Request(link.url, callback=self.parse,meta={'flag': False})
yield new_request