# 常用做法
> 译者:[OSGeo 中国](https://www.osgeo.cn/)
本节记录使用Scrapy时的常见做法。这些内容涵盖了许多主题,通常不属于任何其他特定部分。
## 从脚本中运行Scrapy
你可以使用 [API](api.html#topics-api) 从脚本运行scrapy,而不是运行scrapy via的典型方式 `scrapy crawl` .
记住,scrappy构建在TwistedAsynchronicNetworkLibrary之上,所以需要在TwistedReactor中运行它。
你能用来运行 Spider 的第一个工具是 `scrapy.crawler.CrawlerProcess` . 这个类将为您启动一个扭曲的反应器,配置日志记录和设置关闭处理程序。这个类是所有slapy命令使用的类。
下面是一个示例,演示如何使用它运行单个 Spider 。
```py
import scrapy
from scrapy.crawler import CrawlerProcess
class MySpider(scrapy.Spider):
# Your spider definition
...
process = CrawlerProcess({
'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
})
process.crawl(MySpider)
process.start() # the script will block here until the crawling is finished
```
一定要检查 `CrawlerProcess` 了解其使用细节的文档。
如果您在一个零碎的项目中,有一些额外的帮助器可以用来导入项目中的那些组件。你可以自动输入 Spider 的名字 `CrawlerProcess` 及使用 `get_project_settings` 得到一个 [`Settings`](api.html#scrapy.settings.Settings "scrapy.settings.Settings") 具有项目设置的实例。
下面是一个如何使用 [testspiders](https://github.com/scrapinghub/testspiders) 以项目为例。
```py
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` . 这个类是一个薄包装器,它封装了一些简单的帮助器来运行多个爬行器,但是它不会以任何方式启动或干扰现有的反应器。
使用这个类,在调度spider之后应该显式地运行reactor。建议您使用 `CrawlerRunner` 而不是 `CrawlerProcess` 如果您的应用程序已经在使用Twisted,并且您希望在同一个反应器中运行Scrapy。
请注意, Spider 完成后,您还必须自己关闭扭曲的反应堆。这可以通过将回调添加到由 `CrawlerRunner.crawl` 方法。
下面是一个使用它的例子,以及在 `MySpider` 已完成运行。
```py
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](https://twistedmatrix.com/documents/current/core/howto/reactor-basics.html) .
## 在同一进程中运行多个spider
默认情况下,当您运行时,scrapy为每个进程运行一个spider `scrapy crawl` . 但是,Scrapy支持使用 [internal API](api.html#topics-api) .
下面是一个同时运行多个 Spider 的示例:
```py
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` :
```py
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
```
同样的例子,但是通过链接延迟来按顺序运行spider:
```py
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
```
参见
[从脚本中运行Scrapy](#run-from-script) .
## 分布式爬行
Scrapy不提供任何以分布式(多服务器)方式运行爬虫的内置工具。但是,有一些分发爬行的方法,这取决于您计划如何分发爬行。
如果您有许多 Spider ,那么分配负载的最明显的方法就是设置许多ScrapyD实例,并将 Spider 运行分布在这些实例中。
如果您想在多台机器上运行一个(大) Spider ,通常需要对URL进行分区,以便爬行并将它们发送到每个单独的 Spider 。下面是一个具体的例子:
首先,准备要爬网的URL列表并将其放入单独的文件/URL::
```py
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 会收到一个( Spider )论点 `part` 使用要爬网的分区的编号::
```py
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
```
## 避免被禁止
一些网站实施了某些措施,以防止僵尸爬行他们,不同程度的复杂度。绕开这些措施既困难又棘手,有时可能需要特殊的基础设施。请考虑联系 [commercial support](https://scrapy.org/support/) 如果有疑问。
以下是处理此类网站时要记住的一些提示:
* 将你的用户代理从浏览器中的一个著名的池中轮换出来(用google搜索以获得一个列表)。
* 禁用cookies(请参见 [`COOKIES_ENABLED`](downloader-middleware.html#std:setting-COOKIES_ENABLED) )因为有些网站可能会使用cookie来发现机器人行为
* 使用下载延迟(2或更高)。见 [`DOWNLOAD_DELAY`](settings.html#std:setting-DOWNLOAD_DELAY) 设置。
* 如果可能,使用 [Google cache](http://www.googleguide.com/cached_pages.html) 获取页面,而不是直接访问站点
* 使用一个旋转的IP池。例如,自由 [Tor project](https://www.torproject.org/) 或者像这样的付费服务 [ProxyMesh](https://proxymesh.com/) . 开源替代方案是 [scrapoxy](https://scrapoxy.io/) ,可以将自己的代理附加到的超级代理。
* 使用一个在内部绕过BAN的高度分布式下载程序,这样您就可以专注于解析干净的页面。这种下载器的一个例子是 [Crawlera](https://scrapinghub.com/crawlera)
如果您仍然无法阻止您的bot被禁止,请考虑联系 [commercial support](https://scrapy.org/support/) .
- 简介
- 第一步
- Scrapy at a glance
- 安装指南
- Scrapy 教程
- 实例
- 基本概念
- 命令行工具
- Spider
- 选择器
- 项目
- 项目加载器
- Scrapy shell
- 项目管道
- Feed 导出
- 请求和响应
- 链接提取器
- 设置
- 例外情况
- 内置服务
- Logging
- 统计数据集合
- 发送电子邮件
- 远程登录控制台
- Web服务
- 解决具体问题
- 常见问题
- 调试spiders
- Spider 合约
- 常用做法
- 通用爬虫
- 使用浏览器的开发人员工具进行抓取
- 调试内存泄漏
- 下载和处理文件和图像
- 部署 Spider
- AutoThrottle 扩展
- Benchmarking
- 作业:暂停和恢复爬行
- 延伸 Scrapy
- 体系结构概述
- 下载器中间件
- Spider 中间件
- 扩展
- 核心API
- 信号
- 条目导出器
- 其余所有
- 发行说明
- 为 Scrapy 贡献
- 版本控制和API稳定性