scrapy + celery:

Scrapy原生不支持js渲染,需要单独下载[scrapy-splash](GitHub - scrapy-plugins/scrapy-splash: Scrapy+Splash for JavaScript integration),

scrapy建议和BeautifulSoup4一起使用,BeautifulSoup4是专门分析路径的库。

附:

Celery最佳实践:

1,不要使用数据库作为你的AMQP Broker

2,使用更多的queue(不要只用默认的)

3,使用具有优先级的workers

4,使用Celery的错误处理机制

5,使用Flower

6,没事别太关注任务退出状态

7,不要给任务传递 Database/ORM 对象

作为一个Celery使用重度用户,看到 Celery Best Practices 这篇文章,干脆翻译出来,同时也会加入我们项目中celery的实战经验。

通常在使用Django的时候,你可能需要执行一些长时间的后台任务,没准你可能需要使用一些能排序的任务队列,那么Celery将会是一个非常好的选择。

当把Celery作为一个任务队列用于很多项目中后,作者积累了一些最佳实践方式,譬如如何用合适的方式使用Celery,以及一些Celery提供的但是还未充分使用的特性。

1,不要使用数据库作为你的AMQP Broker

数据库并不是天生设计成能用于AMQP broker的,在生产环境下,它很有可能在某时候当机(PS,当掉这点我觉得任何系统都不能保证不当吧!!!)。

作者猜想为啥很多人使用数据库作为broker主要是因为他们已经有一个数据库用来给web app提供数据存储了,于是干脆直接拿来使用,设置成Celery的broker是很容易的,并且不需要再安装其他组件(譬如RabbitMQ)。

假设有如下场景:你有4个后端workers去获取并处理放入到数据库里面的任务,这意味着你有4个进程为了获取最新任务,需要频繁地去轮询数据库,没准每个worker同时还有多个自己的并发线程在干这事情。

某 一天,你发现因为太多的任务产生,4个worker不够用了,处理任务的速度已经大大落后于生产任务的速度,于是你不停去增加worker的数量。突然, 你的数据库因为大量进程轮询任务而变得响应缓慢,磁盘IO一直处于高峰值状态,你的web应用也开始受到影响。这一切,都因为workers在不停地对数 据库进行DDOS。

而 当你使用一个合适的AMQP(譬如RabbitMQ)的时候,这一切都不会发生,以RabbitMQ为例,首先,它将任务队列放到内存里面,你不需要去访 问硬盘。其次,consumers(也就是上面的worker)并不需要频繁地去轮询因为RabbitMQ能将新的任务推送给consumers。当然, 如果RabbitMQ真出现问题了,至少也不会影响到你的web应用。

这也就是作者说的不用数据库作为broker的原因,而且很多地方都提供了编译好的RabbitMQ镜像,你都能直接使用,譬如 这些 。

对 于这点,我是深表赞同的。我们系统大量使用Celery处理异步任务,大概平均一天几百万的异步任务,以前我们使用的mysql,然后总会出现任务处理延 时太严重的问题,即使增加了worker也不管用。于是我们使用了redis,性能提升了很多。至于为啥使用mysql很慢,我们没去深究,没准也还真出 现了DDOS的问题。

2,使用更多的queue(不要只用默认的)

Celery非常容易设置,通常它会使用默认的queue用来存放任务(除非你显示指定其他queue)。通常写法如下:

@app.task()
def my_taskA(a, b, c): print("doing something here...") @app.task() def my_taskB(x, y): print("doing something here...")

这 两个任务都会在同一个queue里面执行,这样写其实很有吸引力的,因为你只需要使用一个decorator就能实现一个异步任务。作者关心的是 taskA和taskB没准是完全两个不同的东西,或者一个可能比另一个更加重要,那么为什么要把它们放到一个篮子里面呢?(鸡蛋都不能放到一个篮子里 面,是吧!)没准taskB其实不怎么重要,但是量太多,以至于重要的taskA反而不能快速地被worker进行处理。增加workers也解决不了这 个问题,因为taskA和taskB仍然在一个queue里面执行。

3,使用具有优先级的workers

为了解决2里面出现的问题,我们需要让taskA在一个队列Q1,而taskB在另一个队列Q2执行。同时指定 x  workers去处理队列Q1的任务,然后使用其它的workers去处理队列Q2的任务。使用这种方式,taskB能够获得足够的workers去处理,同时一些优先级workers也能很好地处理taskA而不需要进行长时间的等待。

首先手动定义queue

CELERY_QUEUES = (Queue('default', Exchange('default'), routing_key='default'), Queue('for_task_A', Exchange('for_task_A'), routing_key='for_task_A'), Queue('for_task_B', Exchange('for_task_B'), routing_key='for_task_B'), )

然后定义routes用来决定不同的任务去哪一个queue

CELERY_ROUTES = {'my_taskA': {'queue': 'for_task_A', 'routing_key': 'for_task_A'}, 'my_taskB': {'queue': 'for_task_B', 'routing_key': 'for_task_B'}, }

最后再为每个task启动不同的workers celery worker -E -l INFO -n workerA -Q for_task_A celery worker -E -l INFO -n workerB -Q for_task_B

在 我们项目中,会涉及到大量文件转换问题,有大量小于1mb的文件转换,同时也有少量将近20mb的文件转换,小文件转换的优先级是最高的,同时不用占用很 多时间,但大文件的转换很耗时。如果将转换任务放到一个队列里面,那么很有可能因为出现转换大文件,导致耗时太严重造成小文件转换延时的问题。

所以我们按照文件大小设置了3个优先队列,并且每个队列设置了不同的workers,很好地解决了我们文件转换的问题。

4,使用Celery的错误处理机制

大 多数任务并没有使用错误处理,如果任务失败,那就失败了。在一些情况下这很不错,但是作者见到的多数失败任务都是去调用第三方API然后出现了网络错误, 或者资源不可用这些错误,而对于这些错误,最简单的方式就是重试一下,也许就是第三方API临时服务或者网络出现问题,没准马上就好了,那么为什么不试着 重试一下呢?

@app.task(bind=True, default_retry_delay=300, max_retries=5)
def my_task_A(): try: print("doing stuff here...") except SomeNetworkException as e: print("maybe do some clenup here....") self.retry(e)

作者喜欢给每一个任务定义一个等待多久重试的时间,以及最大的重试次数。当然还有更详细的参数设置,自己看文档去。

对于错误处理,我们因为使用场景特殊,例如一个文件转换失败,那么无论多少次重试都会失败,所以没有加入重试机制。

5,使用Flower

Flower 是一个非常强大的工具,用来监控celery的tasks和works。

这玩意我们也没怎么使用,因为多数时候我们都是直接连接redis去查看celery相关情况了。貌似挺傻逼的对不,尤其是celery在redis里面存放的数据并不能方便的取出来。

6,没事别太关注任务退出状态

一个任务状态就是该任务结束的时候成功还是失败信息,没准在一些统计场合,这很有用。但我们需要知道,任务退出的状态并不是该任务执行的结果,该任务执行的一些结果因为会对程序有影响,通常会被写入数据库(例如更新一个用户的朋友列表)。

作者见过的多数项目都将任务结束的状态存放到sqlite或者自己的数据库,但是存这些真有必要吗,没准可能影响到你的web服务的,所以作者通常设置 CELERY_IGNORE_RESULT = True 去丢弃。

对于我们来说,因为是异步任务,知道任务执行完成之后的状态真没啥用,所以果断丢弃。

7,不要给任务传递 Database/ORM 对象

这个其实就是不要传递Database对象(例如一个用户的实例)给任务,因为没准序列化之后的数据已经是过期的数据了。所以最好还是直接传递一个user id,然后在任务执行的时候实时的从数据库获取。

对于这个,我们也是如此,给任务只传递相关id数据,譬如文件转换的时候,我们只会传递文件的id,而其它文件信息的获取我们都是直接通过该id从数据库里面取得。

最后

后面就是我们自己的感触了,上面作者提到的Celery的使用,真的可以算是很好地实践方式,至少现在我们的Celery没出过太大的问题,当然小坑还是有的。至于RabbitMQ,这玩意我们是真没用过,效果怎么样不知道,至少比mysql好用吧。

转载于:https://www.cnblogs.com/welhzh/p/6085424.html

python的分布式爬虫框架相关推荐

  1. 一个自定义python分布式爬虫框架。

    一个分布式爬虫框架.比scrapy简单很多,不需要各种item pipeline middwares spider settings run文件之间来回切换写代码,这只需要一个文件,开发时候可以节约很 ...

  2. python分布式爬虫框架_python之简单Scrapy分布式爬虫的实现

    分布式爬虫:爬虫共用同一个爬虫程序,即把同一个爬虫程序同时部署到多台电脑上运行,这样可以提高爬虫速度. 在默认情况下,scrapy爬虫是单机爬虫,只能在一台电脑上运行,因为爬虫调度器当中的队列queu ...

  3. 基于redis的简易分布式爬虫框架

    代码地址如下: http://www.demodashi.com/demo/13338.html 开发环境 Python 3.6 Requests Redis 3.2.100 Pycharm(非必需, ...

  4. python 大数据开发框架有哪些_大数据分析Python有哪些爬虫框架?

    一.Scrapy Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架.可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中..用这个框架可以轻松爬下来如亚马逊商品信息之类的数 ...

  5. Scrapy-Redis分布式爬虫框架详解-邮乐网(ule.com)

    python编程快速上手(持续更新中-) python爬虫从入门到精通 Scrapy爬虫框架 文章目录 python编程快速上手(持续更新中-) python爬虫从入门到精通 Scrapy爬虫框架 一 ...

  6. Scrapy+Scrapy-redis+Scrapyd+Gerapy 分布式爬虫框架整合

    简介:给正在学习的小伙伴们分享一下自己的感悟,如有理解不正确的地方,望指出,感谢~ 首先介绍一下这个标题吧~ 1. Scrapy:是一个基于Twisted的异步IO框架,有了这个框架,我们就不需要等待 ...

  7. python流行的爬虫框架_Python爬虫相关框架

    Python爬虫相关框架,Python的爬虫框架就是一些爬虫项目的半成品.比如我们可以将一些常见爬虫功能的实现代码写好,然后留下一些接口,在做不同的爬虫项目时,我们只需要根据实际情况,只需要写少量需要 ...

  8. Python使用Scrapy爬虫框架爬取天涯社区小说“大宗师”全文

    大宗师是著名网络小说作家蛇从革的系列作品"宜昌鬼事"之一,在天涯论坛具有超级高的访问量.这个长篇小说于2015年3月17日开篇,并于2016年12月29日大结局,期间每天有7万多读 ...

  9. python虚拟机分布式爬虫_分布式爬虫实战

    一.环境搭建 由于条件有限,一台虚拟机,一台笔记本. 在虚拟机上装上mongodb数据库.redis数据库.redis_scrapy.pymongo.scrapyd 在本地电脑上装上monodb数据库 ...

最新文章

  1. 入门深度学习,先看看三位顶级大牛Yann LeCun、Yoshua Bengio和Geoffrey Hinton的联合综述
  2. paip.元数据驱动的转换-读取文件行到个list理念 uapi java php python总结
  3. 一些有用的Linux命令
  4. 51CTO,什么情况?
  5. 【练习】2021下半年数据结构刷题笔记和总结 (一)(图和动态规划)
  6. 【机器视觉学习笔记】双边滤波算法(C++)
  7. 美国最受欢迎的电商网站,竟然是一家中国公司?
  8. html5实现饼图和线图-我们到底能走多远系列(34)
  9. java逻辑判断_阿里JAVA开发强制要求的10条条件控制及逻辑判断的规范,切记
  10. 洛谷P1120【小木棍】(搜索+剪枝)
  11. 多页Excel转换成PDF时如何保存为单独文件
  12. linux卡片电脑设计,ThinkPad重大更新!5款创意设计PC齐发2日
  13. Youtube——如何将视频中的英文字幕转换成中文字幕
  14. 计算机房等电位连接,《计算机房屏蔽及等电位防护措施原稿2021版》
  15. github网络安全项目工具集合
  16. 133.Python修炼之路【138-前端-JQuery-Json】2018.08.02
  17. 你还在纠结用什么库写 Python 命令行程序?看这一篇就够了
  18. Dreamweaver CS6 Mac破解版
  19. python爬虫是数据挖掘吗_爬虫属于数据挖掘 python为什么叫爬虫
  20. 数据挖掘课程笔记--分类(4)朴素贝叶斯

热门文章

  1. 火焰图:全局视野的Linux性能剖析
  2. 【Python】绘制 对数函数
  3. 关于uni-app入门看完这篇就够了
  4. Edge浏览器上方不展示收藏夹的内容
  5. 直接数字下变频(2):贝塞尔插值法
  6. 「兔了个兔」看我如何抓取兔兔图片到本地(附源码)
  7. 中国的地理位置的表述
  8. 【GDOUCTF2023】wp
  9. keytool 错误: java.lang.Exception: 密钥库文件不存在: keystore
  10. 嵌入式软件开发培训笔记——boot原理与u-boot 基于Cortex_A8核的S5PC100芯片