使用Scrapy爬网多个域而不会纵横交错

时间:2014-06-19 21:59:00

标签: python scrapy

我已经设置了一个聚合所有出站链接的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
  • 更重要的是:如果网站已连接,蜘蛛会从exampleA.com跳到exampleB.com,因为两者都在allowed_domains中?我需要避免这种纵横交错,因为我后来想要计算每个网站的出站链接,以获取有关网站之间关系的信息!

那么我怎样才能扩展更多蜘蛛而不会遇到纵横交错的问题并使用每个网站的设置?

显示我想要实现的内容的附加图像: scrapy

2 个答案:

答案 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中)(因为这意味着您已经访问过它们)。可能有更复杂的方法可以提供更好的性能,但这些也很难实现。