Common Practices

本节介绍了使用Scrapy时的常见做法. 这些是涵盖许多主题的内容,通常不会属于任何其他特定部分.

Run Scrapy from a script

您可以使用API从脚本运行Scrapy,而不是通过scrapy crawl运行Scrapy的典型方式.

请记住,Scrapy构建在Twisted异步网络库的顶部,因此您需要在Twisted反应器中运行它.

您可以用来运行Spider的第一个实用程序是scrapy.crawler.CrawlerProcess . 此类将为您启动Twisted反应器,配置日志记录并设置关闭处理程序. 此类是所有Scrapy命令使用的类.

这是显示如何使用它运行单个蜘蛛的示例.

import scrapy
from scrapy.crawler import CrawlerProcess

class MySpider(scrapy.Spider):
    # Your spider definition
    ...

process = CrawlerProcess(settings={
    'FEED_FORMAT': 'json',
    'FEED_URI': 'items.json'
})

process.crawl(MySpider)
process.start() # the script will block here until the crawling is finished

在CrawlerProcess中的字典中定义设置. 确保检查CrawlerProcess文档以了解其用法详细信息.

如果您在Scrapy项目中,则可以使用一些其他帮助器将这些组件导入项目中. 您可以自动将蜘蛛的名称传递给CrawlerProcess ,并使用get_project_settings来获取包含项目设置的Settings实例.

接下来是一个有效的示例,以testspiders项目为例.

from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings

process = CrawlerProcess(get_project_settings())

# 'followall' is the name of one of the spiders of the project.
process.crawl('followall', domain='scrapinghub.com')
process.start() # the script will block here until the crawling is finished

还有另一个Scrapy实用程序,可以对爬网过程进行更多控制: scrapy.crawler.CrawlerRunner . 此类是一个瘦包装程序,它封装了一些简单的帮助程序以运行多个搜寻器,但是它不会以任何方式启动或干扰现有的反应堆.

使用此类,应在安排好蜘蛛后明确运行反应堆. 如果您的应用程序已在使用Twisted,并且您希望在同一反应堆中运行Scrapy,则建议您使用CrawlerRunner而不是CrawlerProcess .

请注意,在完成定位器之后,您还必须自行关闭Twisted反应堆. 这可以通过将回调添加到CrawlerRunner.crawl方法返回的deferred中来实现.

这是其用法的一个示例,以及在MySpider完成运行后手动停止反应堆的回调.

from twisted.internet import reactor
import scrapy
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging

class MySpider(scrapy.Spider):
    # Your spider definition
    ...

configure_logging({'LOG_FORMAT': '%(levelname)s: %(message)s'})
runner = CrawlerRunner()

d = runner.crawl(MySpider)
d.addBoth(lambda _: reactor.stop())
reactor.run() # the script will block here until the crawling is finished

也可以看看

Twisted Reactor Overview.

Running multiple spiders in the same process

默认情况下,当您运行scrapy crawl时,Scrapy会为每个进程运行一个蜘蛛. 但是,Scrapy支持使用内部API在每个进程中运行多个蜘蛛.

这是一个同时运行多个蜘蛛的示例:

import scrapy
from scrapy.crawler import CrawlerProcess

class MySpider1(scrapy.Spider):
    # Your first spider definition
    ...

class MySpider2(scrapy.Spider):
    # Your second spider definition
    ...

process = CrawlerProcess()
process.crawl(MySpider1)
process.crawl(MySpider2)
process.start() # the script will block here until all crawling jobs are finished

使用CrawlerRunner相同示例:

import scrapy
from twisted.internet import reactor
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging

class MySpider1(scrapy.Spider):
    # Your first spider definition
    ...

class MySpider2(scrapy.Spider):
    # Your second spider definition
    ...

configure_logging()
runner = CrawlerRunner()
runner.crawl(MySpider1)
runner.crawl(MySpider2)
d = runner.join()
d.addBoth(lambda _: reactor.stop())

reactor.run() # the script will block here until all crawling jobs are finished

相同的示例,但是通过链接延迟项来依次运行蜘蛛程序:

from twisted.internet import reactor, defer
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging

class MySpider1(scrapy.Spider):
    # Your first spider definition
    ...

class MySpider2(scrapy.Spider):
    # Your second spider definition
    ...

configure_logging()
runner = CrawlerRunner()

@defer.inlineCallbacks
def crawl():
    yield runner.crawl(MySpider1)
    yield runner.crawl(MySpider2)
    reactor.stop()

crawl()
reactor.run() # the script will block here until the last crawl call is finished

也可以看看

Run Scrapy from a script.

Distributed crawls

Scrapy没有提供任何内置功能来以分布式(多服务器)方式运行爬网. 但是,有一些分发爬网的方法,具体取决于您计划分发爬网的方式.

如果您有许多Spider,则分配负载的明显方法是设置许多Scrapyd实例并在其中实例中分配Spider运行.

如果您想在多个计算机上运行单个(大型)蜘蛛,通常要做的就是对URL进行分区以进行爬网,然后将其发送到每个单独的蜘蛛. 这是一个具体的例子:

首先,您准备要爬网的URL列表并将其放入单独的文件/ 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服务器上运行一个Spider. 蜘蛛将收到一个(spider)参数part ,其中包含要爬网的分区号:

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

Avoiding getting banned

一些网站实施了某些措施,以防止机器人以不同程度的复杂程度对其进行爬网. 绕开这些措施可能是困难而棘手的,有时可能需要特殊的基础结构. 如有疑问,请考虑联系商业支持 .

处理这些类型的网站时,请牢记以下提示:

  • 从浏览器中的一系列知名用户中轮流使用您的用户代理(四处搜索以获取它们的列表)
  • 禁用cookie(请参阅COOKIES_ENABLED ),因为某些网站可能使用cookie来发现机器人行为
  • 使用下载延迟(2或更高). 请参阅DOWNLOAD_DELAY设置.
  • 如果可能,请使用Google缓存来获取页面,而不要直接访问这些网站
  • 使用旋转IP池. 例如,免费的Tor项目或类似ProxyMesh的付费服务. 开源替代方案是scrapoxy ,您可以将自己的代理附加到超级代理.
  • 使用可以在内部规避禁令的高度分散的下载器,因此您可以专注于解析干净的页面. 此类下载器的一个示例是Crawlera

如果仍然无法阻止您的漫游器被禁用,请考虑与商业支持联系.