我想废弃一堆网页。提供不同的数据罐,然后再进行匹配。
[Page1]-Get-PostProcessing-Store-[Pot1]-+
[Page2]-Get-PostProcessing-Store-[Pot2]-+--Match---[ResultPage]-REST-API
[Page3]-Get-PostProcessing-Store-[Pot3]-+
...
现在我想考虑每个页面的管道尽可能独立。有时页面需要JavaScript抓取功能,有时候不需要。有时候我还需要抓图像,有时只抓PDF。
我用一页和Scrapy做了一个原型。我真的有这个结构,我不知道如何“拆分”它的剪贴板和中间件是独立的每个页面。另一方面,lxml足够吗?如何处理机器人并等待延迟以避免阻塞?添加消息队列是否有意义?
实施这一切的最佳方法是什么?请具体!我的主要问题是组织我的代码和使用工具的结构。
答案 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
可能,是的。但是,学习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和一只正在运行的蜘蛛开始,并从中进行迭代,改善它真正需要的地方。
我希望这会有所帮助。