我已经设置了一个聚合所有出站链接的CrawlSpider(仅从start_urls
抓取一定深度,例如DEPTH_LIMIT = 2
)。
class LinkNetworkSpider(CrawlSpider):
name = "network"
allowed_domains = ["exampleA.com"]
start_urls = ["http://www.exampleA.com"]
rules = (Rule(SgmlLinkExtractor(allow=()), callback='parse_item', follow=True),)
def parse_start_url(self, response):
return self.parse_item(response)
def parse_item(self, response):
hxs = HtmlXPathSelector(response)
links = hxs.select('//a/@href').extract()
outgoing_links = []
for link in links:
if ("http://" in link):
base_url = urlparse(link).hostname
base_url = base_url.split(':')[0] # drop ports
base_url = '.'.join(base_url.split('.')[-2:]) # remove subdomains
url_hit = sum(1 for i in self.allowed_domains if base_url not in i)
if url_hit != 0:
outgoing_links.append(link)
if outgoing_links:
item = LinkNetworkItem()
item['internal_site'] = response.url
item['out_links'] = outgoing_links
return [item]
else:
return None
我想将其扩展到多个域(exampleA.com,exampleB.com,exampleC.com ......)。起初,我想我可以将我的列表添加到start_urls
以及allowed_domains
,但在我看来,这会导致以下问题:
DEPTH_LIMIT
/ start_urls
应用设置allowed_domain
?那么我怎样才能扩展更多蜘蛛而不会遇到纵横交错的问题并使用每个网站的设置?
显示我想要实现的内容的附加图像:
答案 0 :(得分:3)
我现在已经没有规则地实现了它。我为每个meta
添加了start_url
属性,然后只需检查自己链接是否属于原始域,并相应地发送新请求。
因此,覆盖start_requests
:
def start_requests(self):
return [Request(url, meta={'domain': domain}, callback=self.parse_item) for url, domain in zip(self.start_urls, self.start_domains)]
在后续解析方法中,我们抓取meta
属性domain = response.request.meta['domain']
,将域与提取的链接进行比较,并自行发送新请求。
答案 1 :(得分:1)
您可能需要保留抓取工具已访问过的网址的数据结构(例如散列图)。然后,只需要在访问它们时将URL添加到hashmap,而不是访问URL(如果它们已经在hashmap中)(因为这意味着您已经访问过它们)。可能有更复杂的方法可以提供更好的性能,但这些也很难实现。