递归地抓取网站及其外部链接,为Python

时间:2017-11-25 18:28:40

标签: python beautifulsoup scrapy web-crawler scrapy-spider

我有这个项目,我正在尝试整理数据分析实验。我有一个管道,但我不知道如何继续获取我需要的数据。 我想抓取一个网站并查找所有内部和外部链接,将它们分开并递归地抓取外部链接,直到达到一定深度。我想这样做是为了创建一个网站所有连接的图形,然后使用中心算法找到中心节点并从那里继续。 理想情况下,我想在这个项目中使用python 2。 我看过scrapy,美丽的汤和其他图书馆,但这一切都让人很困惑。

在抓取和创建图表时,我们非常感谢任何帮助和/或建议

谢谢

编辑:

我正在尝试实现您建议的解决方案,并使用下面的代码,我可以在调试信息中看到它正在查找链接,但要么它们没有保存在LinkList类中,要么我提取它们错误他们正在过滤。

有什么建议吗?

class LinkList(Item):
    url = Field()

class WebcrawlerSpider(CrawlSpider):
    name = 'webcrawler'
    allowed_domains = ['https://www.wehiweb.com']
    start_urls = ['https://www.wehiweb.com']

rules = (
    Rule(LxmlLinkExtractor(allow=()), callback='parse_obj', follow=True),
)

def parse_obj(self,response):
    item = LinkList()
    item['url'] = []
    for link in LxmlLinkExtractor(allow=(),deny = self.allowed_domains).extract_links(response):
        item['url'].append(link.url)
        yield item

def main():
    links = LinkList()
    process = CrawlerProcess()
    process.crawl(WebcrawlerSpider)
    process.start()
    print(links.items())

if __name__ == "__main__":
    main()

1 个答案:

答案 0 :(得分:0)

Scrapy应该可以正常使用。大多数人使用它从网站中提取数据(抓取),但它也可以用于简单的抓取。

在scrapy中,您可以抓取抓取网站并关注链接的蜘蛛。 scrapy项目可以包含许多蜘蛛,但在标准设置中,每个蜘蛛都有自己的队列并执行自己的任务。

正如您描述的用例,我建议使用两个独立的scrapy蜘蛛:

  • 一个用于现场抓取,仅针对此域设置allowed_domains设置,以及非常高甚至0(=无限)MAX_DEPTH设置,以便它将抓取整个域
  • 一个用于非现场抓取,其中空allowed_domains(将允许所有域)和低MAX_DEPTH设置,以便在一定数量的跃点后停止

parse方法的角度来看,scrapy有RequestItem的概念。您可以从解析响应的方法返回RequestItem

  • 请求会触发scrapy访问网站,然后在结果上调用parse方法
  • 项目允许您指定为项目定义的结果

因此,无论何时您想要关注某个链接,您都会从解析方法中yield Request。对于项目的所有结果,您将获得Item

在你的情况下,我说你的Item是这样的:

class LinkItem(scrapy.Item):
    link_source = scrapy.Field()
    link_target = scrapy.Field()

如果您在页面link_source="http://example.com/", link_target="http://example.com/subsite"上,并且找到指向http://example.com/的链接,则可以返回/subsite项:

def parse(self, response):
    # Here: Code to parse the website (e.g. with scrapy selectors 
    # or beautifulsoup, but I think scrapy selectors should
    # suffice

    # after parsing, you have a list "links"
    for link in links:
        yield Request(link)  # make scrapy continue the crawl

        item = LinkItem()
        item['link_source'] = response.url
        item['link_target'] = link
        yield item  # return the result we want (connections in link graph)

您可能会看到我没有进行任何深度检查等。您不必在parse方法中手动执行此操作,scrapy附带Middleware。其中一个中间件名为OffsiteMiddleware,将检查您的蜘蛛是否可以访问特定域(使用选项allowed_domains,检查scrapy教程)。另一个是DepthMiddleware(也请查看教程)。

这些结果可以写在任何你想要的地方。 Scrapy附带了一个名为feed exports的东西,它允许您将数据写入文件。如果您需要更高级的东西,例如一个数据库,你可以看看scrapy' Pipeline

除了scrapy之外,我目前还没有其他库和项目的需要。

当然,当您想要处理数据时,您可能需要专门的数据结构而不是纯文本文件。