4

最近,我一直在尝试掌握scrapy。我觉得如果我对架构有更好的理解,我会走得更快。当前,我遇到的具体问题是:我想将scrapy提取的所有链接存储在数据库中,而不是响应,链接。这是为了进行完整性检查。

我最初的想法是process_links在 a 上使用参数并在它指向的函数中rule生成。items然而,虽然callback参数指向一个作为项目生成器的函数,但process_links参数的工作方式更像是一个过滤器。在该callback功能中,您产生项目,它们会被自动收集并放入管道中。在process_links函数中,您返回链接列表。您不生成项目。

我可以在process_links函数中建立一个数据库连接并直接写入数据库,但是当scrapy通过Twisted内置异步数据库事务处理时,这感觉不是正确的方法。

我可以尝试将项目从process_links函数传递给callback函数,但我不确定这两个函数之间的关系。一个用于生成项目,一个接收列表并返回列表。

在尝试思考这一点时,我不断遇到这样一个事实,即我不了解 scapy 中的控制循环。读取函数产生的项目的过程是什么callback?向函数提供链接并从process_links函数接收链接的过程是什么?requests取回的那个responses

从我的角度来看,我在一个流派的蜘蛛中编写代码items。会items 自动读取并通过管道移动。我可以在管道中创建代码,并且items会自动传入和传出该代码。items缺少的是我对这些如何通过管道移动的确切理解。

查看代码我可以看到蜘蛛的基本代码隐藏在角落里,所有好的蜘蛛都应该这样做,并以__init__.py. 它包含starts_requests() 和make_requests_from_url()函数,根据文档是起点。但这不是一个控制循环。它被别的东西调用了。

从相反的方向走,我可以看到,当我执行scrapy crawl...我正在调用的命令时crawl.py,它又调用self.crawler_process.start()crawler.py. 这启动了一个 Twisted 反应堆。还有core/engine.py另一个函数集合,看起来好像它们旨在控制蜘蛛的操作。

尽管浏览了代码,但我对整个过程并没有清晰的心理印象。我意识到框架的想法是它隐藏了很多复杂性,但我觉得通过更好地理解正在发生的事情,我可以更好地利用框架。

对不起,很长的帖子。如果有人可以回答我关于保存数据库链接的具体问题,那就太好了。如果您能够对架构进行简要概述,那将非常有帮助。

4

2 回答 2

4

我不久前开始使用 Scrapy,我自己也有一些疑问(考虑到我是从整体上开始使用 Python 的),但现在它对我有用,所以不要气馁——它是一个很好的框架。

首先,在这个阶段我不会太担心框架背后的细节,而是自己开始编写一些基本的蜘蛛。

一些真正关键的概念是:

  • Start_urls – 它们定义了一个初始 URL(或多个 URL),您将在其中进一步查找文本或要抓取的进一步链接。假设您想从例如http://x.com

  • Parse(self.response) 方法——这将是第一个被处理的方法,它会给你http://x.com的响应。(基本上是它的 HTML 标记)

  • 您可以使用 Xpath 或 CSS 选择器从该标记中提取信息,例如a = Response.Xpath(‘//div[@class=”foo”]/@href’)将提取到页面的链接(例如http://y.com

  • 如果您想提取链接的文本,那么字面意思是“ http://y.com ”,您只需在 Parse(self.response) 方法中产生(返回)一个项目。因此,您在此方法中的最终声明将是yield item. 如果您想更深入地访问http://y.com ,您的最终声明将是scrapy.Request(a, callback= self.parse_final)- parse_final 在这里是 parse_final(self.response) 方法的回调示例。

  • 然后你可以提取http://y.com的 html 的元素作为 parse_final(self.response) 方法中的最终调用,或者不断重复该过程以挖掘页面结构中的更多链接

  • 管道用于处理项目。因此,当项目产生时,默认情况下它们只是打印在屏幕上。因此,在管道中,您可以将它们重定向到 csv 文件、数据库等。

整个过程变得更加复杂,当您开始在每个方法中获取更多链接时,根据各种条件调用各种回调等。我认为您应该首先了解这个概念,然后再进入管道。来自 Scrapy 的示例有点难以获得,但是一旦你明白了,它真的很好,而且最终并没有那么复杂。

于 2015-12-16T13:54:21.567 回答
4

简而言之,这就是 Scrapy 的工作原理:

  • 您有负责抓取网站的蜘蛛。您可以为单独的站点/任务使用单独的蜘蛛。
  • 您向蜘蛛提供一个或多个起始 URL。您可以将它们作为列表提供或使用start_requests方法
  • 当我们使用 Scrapy 运行爬虫时,它会获取这些 URL 并获取 HTML 响应。响应被传递给蜘蛛类的回调。您可以在使用该start_requests方法时显式定义回调。如果你不这样做,Scrapy 将使用该parse方法作为回调。
  • 您可以从 HTML 中提取所需的任何数据。您在回调中获得的response对象parse允许您使用 css 选择器或 xpath 提取数据。
  • 如果您从响应中找到数据,则可以构造Items 和yield它们。如果你需要转到另一个页面,你可以 yield scrapy.Request
  • 如果您生成字典或Item对象,Scrapy 将通过已注册的管道发送它们。如果您 yield scrapy.Request,请求将被进一步解析,并且响应将反馈给回调。同样,您可以定义一个单独的回调或使用默认回调。
  • 在管道中,您的数据(字典或Item)通过管道处理器。在管道中,您可以将它们存储在数据库中或您想做的任何事情中。

简而言之:

  • parse方法或蜘蛛内部的任何方法中,我们将提取并产生我们的数据,以便它们通过管道发送。
  • 在管道中,您进行实际处理。

    这是一个简单的蜘蛛和管道示例:https ://gist.github.com/masnun/e85b38a00a74737bb3eb

于 2015-12-16T12:59:14.117 回答