最近,我一直在努力解决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
}
这是另一个函数集合,看起来好像它们是为了控制蜘蛛的操作而设计的。
尽管仔细查看了代码,但我并没有对整个过程有清晰的心理形象。我意识到框架的概念是它隐藏了很多复杂性,但我觉得通过更好地理解正在发生的事情,我可以更好地利用框架。
对不起,很长的帖子。如果有人能够回答我关于保存数据库链接的具体问题,那就太棒了。如果您能够简要概述架构,那将非常有用。
答案 0 :(得分:4)
这就是Scrapy的工作原理:
start_requests
方法start_requests
方法时显式定义回调。如果你不这样做,Scrapy将使用parse
方法作为回调。 response
回调中获得的parse
对象允许您使用css选择器或xpath提取数据。 Item
和yield
。如果您需要转到其他页面,则可以获得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的例子有点难以获得,但是一旦你理解了这个例子它真的很好而且最终并不复杂。