理解scrapy框架架构

时间:2015-12-16 12:10:42

标签: python scrapy scrapy-spider scrapy-pipeline

最近,我一直在努力解决scrapy问题。我觉得如果我对架构有了更好的理解,我会更快地移动。我目前的具体问题是:我希望将scrapy提取的所有链接存储在数据库中,而不是响应,链接。这是为了进行健全性检查。

我最初的想法是在process_links上使用rule参数,并在其指向的函数中生成items。但是,虽然callback参数指向作为项生成器的函数,但process_links参数更像是过滤器。在callback函数中,您可以生成项目,并自动收集它们并将其放入管道中。在process_links函数中,您将返回一个链接列表。你不会生成物品。

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

我可以尝试将项目从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中的core/engine.py。这启动了Twisted反应堆。还有 { "restaurant name" : "str1", "distance": 19.4 } { "restaurant name" : "str2", "distance": 2.1 { "restaurant name" : "str3", "distance":19.3 } { "restaurant name" : "str4", "distance": 2.1 } 这是另一个函数集合,看起来好像它们是为了控制蜘蛛的操作而设计的。

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

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

2 个答案:

答案 0 :(得分:4)

这就是Scrapy的工作原理:

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

简而言之:

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

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

答案 1 :(得分: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)方法的例子。

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

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

当你开始在每种方法中获得更多链接时,整个过程变得更加复杂,基于你调用各种回调等的各种条件。我认为你应该首先在获得管道之前先获得这个概念。来自Scrapy的例子有点难以获得,但是一旦你理解了这个例子它真的很好而且最终并不复杂。