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 足够了吗?如何处理机器人并等待延迟以避免阻塞?添加消息队列有意义吗?
实现这一切的最佳方法是什么?请具体点!我的主要问题是组织代码的结构和要使用的工具。
哇,那里有很多问题。=)
很难针对如此广泛的问题进行具体说明,尤其是不知道您对该工具的熟悉程度。
如果我理解正确的话,你有一个蜘蛛和一个中间件。我没有确切地了解您的中间件代码在做什么,但为了概念证明,我将从一个蜘蛛(可能还有 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)
大概,是的。但是,学习 XPath 是个好主意,如果您还没有的话,可以充分利用它。 这是一个很好的起点。
除非您需要执行 Javascript 代码,然后您可能想尝试插入 Selenium/PhantomJS 或Splash。
如果不需要执行 Javascript 代码,但需要解析 JS 代码中的数据,可以使用js2xml。
要服从robots.txt,设置ROBOTSTXT_OBEY为True。
要配置延迟,请设置DOWNLOAD_DELAY。您还可以尝试使用autothrottle 扩展并查看并发请求设置。
嗯,这取决于你的用例,真的。如果您有一个非常大的爬网(数亿个 URL 或更多),这可能是有意义的。
但是您已经可以使用独立的 Scrapy 免费获得很多东西,包括当现有内存不足以容纳所有挂起的 URL 时的基于磁盘的队列。
您可以配置调度程序将用于内存和磁盘队列的后端,还可以将调度程序与您自己的版本完全交换。
我会从 Scrapy 和一个工作蜘蛛开始,然后迭代,改进真正需要的地方。
我希望这有帮助。