抓取多个页面,保持独立

lon*_*ony 2 python scrapy web-scraping

我想一堆页面。提供不同的数据罐,然后进行匹配。

[Page1]-Get-PostProcessing-Store-[Pot1]-+
[Page2]-Get-PostProcessing-Store-[Pot2]-+--Match---[ResultPage]-REST-API
[Page3]-Get-PostProcessing-Store-[Pot3]-+
...
Run Code Online (Sandbox Code Playgroud)

现在我想尽可能独立考虑每个页面的管道。有时页面需要 JavaScript 抓取功能,有时不需要。有时我还需要抓取图像,有时只需要抓取 PDF。

我用一页和 Scrapy 做了一个原型。我真的有结构,我不知道如何“拆分”它,因为每个页面的刮板和中间件都是独立的。另一方面,lxml 足够了吗?如何处理机器人并等待延迟以避免阻塞?添加消息队列有意义吗?

实现这一切的最佳方法是什么?请具体点!我的主要问题是组织代码的结构和要使用的工具。

Eli*_*les 5

哇,那里有很多问题。=)

很难针对如此广泛的问题进行具体说明,尤其是不知道您对该工具的熟悉程度。

如果我理解正确的话,你有一个蜘蛛和一个中间件。我没有确切地了解您的中间件代码在做什么,但为了概念证明,我将从一个蜘蛛(可能还有 util 函数)中的所有代码开始,让您可以自由地为不同的提取技术使用不同的回调。

一旦你开始工作,那么你可以在需要时考虑制作一个通用的中间件(过早的抽象通常和过早的优化一样糟糕)。

这里有一些想法:

为每个响应实现不同的提取代码

如果您事先知道要调用哪个代码来处理每个请求,只需为该请求设置适当的回调:

def parse(self, response):
    yield scrapy.Request('http://example.com/file.pdf', self.handle_pdf)
    yield scrapy.Request('http://example.com/next_page', self.handle_next_page)

def handle_pdf(self, response):
    "process the response for a PDF request"

def handle_next_page(self, response):
    "process the response for next page"
Run Code Online (Sandbox Code Playgroud)

如果您事先不知道,您可以实现一个回调,相应地分派到其他适当的回调:

def parse(self, response):
    if self.should_grab_images(response):
        for it in self.grab_images(response):
            yield it
    if self.should_follow_links(response):
        for it in self.follow_links(response):
            yield it
Run Code Online (Sandbox Code Playgroud)

lxml 够了吗?

大概,是的。但是,学习 XPath 是个好主意,如果您还没有的话,可以充分利用它。 这是一个很好的起点

除非您需要执行 Javascript 代码,然后您可能想尝试插入 Selenium/PhantomJS 或Splash

如果不需要执行 Javascript 代码,但需要解析 JS 代码中的数据,可以使用js2xml

如何处理机器人并等待延迟以避免阻塞?

要服从robots.txt,设置ROBOTSTXT_OBEYTrue

要配置延迟,请设置DOWNLOAD_DELAY。您还可以尝试使用autothrottle 扩展并查看并发请求设置

添加消息队列有意义吗?

嗯,这取决于你的用例,真的。如果您有一个非常大的爬网(数亿个 URL 或更多),这可能是有意义的。

但是您已经可以使用独立的 Scrapy 免费获得很多东西,包括当现有内存不足以容纳所有挂起的 URL 时的基于磁盘的队列。

您可以配置调度程序将用于内存和磁盘队列的后端,还可以将调度程序与您自己的版本完全交换。

结论

我会从 Scrapy 和一个工作蜘蛛开始,然后迭代,改进真正需要的地方。

我希望这有帮助。