刮刮多页,保持独立

时间:2015-11-15 00:17:03

标签: python web-scraping scrapy

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

[Page1]-Get-PostProcessing-Store-[Pot1]-+
[Page2]-Get-PostProcessing-Store-[Pot2]-+--Match---[ResultPage]-REST-API
[Page3]-Get-PostProcessing-Store-[Pot3]-+
...

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

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

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

1 个答案:

答案 0 :(得分:4)

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

很难针对这么广泛的问题,特别是不知道你对这个工具的熟悉程度。

如果我理解正确,你就有蜘蛛和中间件。 我没有得到您的中间件代码正在做什么,但是为了概念验证,我将从一个蜘蛛(也许是util函数)中的代码开始,让您可以自由地为不同的提取技术使用不同的回调。 / p>

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

以下是一些想法:

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

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

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"

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

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

lxml够了吗?

可能,是的。但是,学习XPath是一个好主意,如果你还没有,可以充分利用它。 Here is a good starting point

除非你需要执行Javascript代码,否则你可能想尝试插入Selenium / PhantomJS或Splash

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

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

要服从robots.txt,请将ROBOTSTXT_OBEY设为True

要配置延迟,请设置DOWNLOAD_DELAY。您也可以试用autothrottle extension并查看concurrent requests settings

添加消息队列是否有意义?

嗯,这取决于你的用例,真的。 如果你有一个非常大的爬行(数以亿计的URL或更多),它可能是有道理的。

但是你已经通过独立的Scrapy免费获得了很多,包括基于磁盘的队列,当现有内存不足以容纳所有待处理的URL时。

您可以配置the backends the scheduler will use for the memory and disk queues并完全交换scheduler with your own version

结论

我从Scrapy和一只正在运行的蜘蛛开始,并从中进行迭代,改善它真正需要的地方。

我希望这会有所帮助。