常见做法
本节介绍使用Scrapy时的常见做法。这些是涵盖许多主题的东西,并不经常属于任何其他特定部分。
从脚本运行Scrapy
您可以使用API从脚本运行Scrapy,而不是通过Scrape爬行运行Scrapy的典型方法。
请记住,Scrapy建立在Twisted异步网络库之上,因此您需要在Twisted反应器内运行它。
您可以使用的第一个实用程序来运行您的蜘蛛是scrapy.crawler.CrawlerProcess。该类将为您启动一个Twisted反应器,配置日志记录并设置关闭处理程序。这个类是所有Scrapy命令使用的类。
这是一个示例,显示如何运行单个蜘蛛。
进口刮板
从scrapy.crawler导入CrawlerProcess
MySpider类(scrapy.Spider):
#你的蜘蛛定义
...
process = CrawlerProcess({
'USER\_AGENT':'Mozilla / 4.0(兼容; MSIE 7.0; Windows NT 5.1)'
})
process.crawl(MySpider)
process.start()#脚本将阻止这里,直到抓取完成
确保检查CrawlerProcess文档以了解其使用细节。
如果您在Scrapy项目中,还有一些额外的帮助者可以在项目中导入这些组件。您可以自动导入将其名称传递给CrawlerProcess的蜘蛛,并使用get_project_settings获取具有项目设置的Settings实例。
以下是使用testspiders项目作为示例的工作示例。
从scrapy.crawler导入CrawlerProcess
从scrapy.utils.project导入get_project_settings
process = CrawlerProcess(get_project_settings())
'followall'是项目的一个蜘蛛的名字。
process.crawl('followall',domain ='scrapinghub.com')
process.start()#脚本将阻止这里,直到抓取完成
还有一个Scrapy实用程序可以更好地控制爬网过程:scrapy.crawler.CrawlerRunner。这个类是一个薄的封装,封装了一些简单的助手来运行多个爬虫,但它不会以任何方式启动或干扰现有的反应器。
使用这个类,反应器应该在调度你的蜘蛛后显式运行。建议您使用CrawlerRunner而不是CrawlerProcess,如果您的应用程序已经使用Twisted,并且要在同一个反应器中运行Scrapy。
请注意,在蜘蛛完成后,您也必须自己关闭Twisted反应堆。这可以通过向CrawlerRunner.crawl方法返回的延迟添加回调来实现。
以下是其使用示例,以及在MySpider完成运行后手动停止反应器的回调。
来自twisted.internet进口反应堆
进口刮板
从scrapy.crawler导入CrawlerRunner
从scrapy.utils.log导入configure_logging
MySpider类(scrapy.Spider):
#你的蜘蛛定义
...
configure_logging({'LOG_FORMAT':'%(levelname)s:%(message)s'})
runner = CrawlerRunner()
d = runner.crawl(MySpider)
d.addBoth(lambda _:reactor.stop())
reactor.run()#脚本将阻止这里,直到爬行完成
也可以看看
扭转反应堆概述。
在同一进程中运行多个蜘蛛
默认情况下,当您执行抓取抓取时,Scrapy会在每个进程中运行一个蜘蛛。但是,Scrapy支持使用内部API在每个进程中运行多个蜘蛛。
这是一个同时运行多个蜘蛛的示例:
进口刮板
从scrapy.crawler导入CrawlerProcess
MySpider1类(scrapy.Spider):
#你的第一个蜘蛛定义
...
MySpider2类(scrapy.Spider):
#你的第二个蜘蛛定义
...
process = CrawlerProcess()
process.crawl(MySpider1)
process.crawl(MySpider2)
process.start()#脚本将阻止这里,直到所有抓取作业完成
使用CrawlerRunner的同一个例子:
进口刮板
来自twisted.internet进口反应堆
从scrapy.crawler导入CrawlerRunner
从scrapy.utils.log导入configure_logging
MySpider1类(scrapy.Spider):
#你的第一个蜘蛛定义
...
MySpider2类(scrapy.Spider):
#你的第二个蜘蛛定义
...
configure_logging()
runner = CrawlerRunner()
runner.crawl(MySpider1)
runner.crawl(MySpider2)
d = runner.join()
d.addBoth(lambda _:reactor.stop())
reactor.run()#脚本将阻止此处,直到所有抓取作业完成
相同的例子,但是通过链接延迟来顺序运行蜘蛛:
从twisted.internet进口反应堆,推迟
从scrapy.crawler导入CrawlerRunner
从scrapy.utils.log导入configure_logging
MySpider1类(scrapy.Spider):
#你的第一个蜘蛛定义
...
MySpider2类(scrapy.Spider):
#你的第二个蜘蛛定义
...
configure_logging()
runner = CrawlerRunner()
@ defer.inlineCallbacks
def crawl():
yield runner.crawl(MySpider1)
产生runner.crawl(MySpider2)
reactor.stop()
爬行()
reactor.run()#脚本将在此停止,直到最后一次爬网调用完成
也可以看看
从脚本运行Scrapy
分布式抓取
Scrapy不提供任何内置的以分布(多服务器)方式运行爬网的功能。但是,有一些方法可以分发爬网,这取决于您计划分发的方式。
如果你有很多蜘蛛,分发负载的明显方法是设置许多Scrapyd实例,并在其中分布蜘蛛运行。
如果您想要通过许多机器运行单个(大)蜘蛛,您通常会做的是分割URL以进行爬网并将其发送到每个单独的蜘蛛。这是一个具体的例子:
首先,您准备要抓取的网址列表,并将其放入单独的文件/网址中:
http://somedomain.com/urls-to-crawl/spider1/part1.list
http://somedomain.com/urls-to-crawl/spider1/part2.list
http://somedomain.com/urls-to-crawl/spider1/part3.list
然后,您可以在3个不同的Scrapyd服务器上启动一个蜘蛛运行。蜘蛛会收到一个(蜘蛛)参数部分,其中要抓取的分区号:
curl http://scrapy1.mycompany.com:6800/schedule.json -d project = myproject -d spider = spider1 -d part = 1
curl http://scrapy2.mycompany.com:6800/schedule.json -d project = myproject -d spider = spider1 -d part = 2
curl http://scrapy3.mycompany.com:6800/schedule.json -d project = myproject -d spider = spider1 -d part = 3
避免被禁止
一些网站采取某些措施来防止机器人爬行,具有不同程度的复杂性。解决这些措施可能是困难和棘手的,有时可能需要特殊的基础设施。如有疑问,请考虑联系商业支持。
在处理这些网站时,请注意以下几点:
从浏览器的一个众所周知的池中旋转你的用户代理(谷歌,以获得它们的列表)
禁用Cookie(请参阅COOKIES_ENABLED),因为某些网站可能会使用Cookie来查找漫游器的行为
使用下载延迟(2或更高)。请参阅DOWNLOAD_DELAY设置。
如果可能,请使用Google缓存来抓取网页,而不是直接点击网站
使用一个旋转IP池。例如,免费的Tor项目或付费服务,如ProxyMesh。一个开源的替代方案是scrapoxy,一个超级代理,你可以附加你自己的代理。
使用高度分布的下载程序来规避内部禁止,所以您可以专注于解析干净的页面。这样的下载器的一个例子是Crawlera
如果您仍然无法阻止您的机器人被禁止,请考虑联系商业支持。