一、写在前面

  在上一篇博客中提到过对于网络爬虫这种包含大量网络请求的任务,是可以用Celery来做到加速爬取的,那么,这一篇博客就要具体说一下怎么用Celery来对我们的爬虫进行一个加速!

二、知识补充

1.class celery.group

  group这个类表示创建一组要并行执行的任务,不过一组任务是懒惰的,所以你需要运行并对其进行评估。要了解这个类,可以查看文档,或者在Pycharm中直接Ctrl+左键就能直接查看源码了,如下图:

  

  当然了,直接看源码还不够,最好还是自己动下手。所以先创建一个test.py,其中代码如下:

 1 from celery import Celery
 2
 3
 4 app = Celery("test", broker="redis://127.0.0.1:6379", backend="redis://127.0.0.1:6379")
 5
 6
 7 @app.task
 8 def add(x, y):
 9     return x + y
10
11
12 if __name__ == '__main__':
13     app.start()

  然后运行Celery服务器,再在test.py所在目录下创建一个test_run.py用于测试,其中代码如下:

 1 from celery import group
 2 from .test import add
 3
 4
 5 lazy_group = group(add.s(2, 2), add.s(4, 4))
 6 print(type(lazy_group))
 7 result = lazy_group()
 8 print(result)
 9 print(type(result))
10 print(result.get())

  在Pycharm中运行test_run.py,得到的结果如下:

<class 'celery.canvas.group'>

fe54f453-eb9c-4b24-87e3-a26fab75967f

<class 'celery.result.GroupResult'>

[4, 8]

  通过查看源码可以知道,是可以往group中传入一个由任务组成的可迭代对象的,所以这就进行一下测试,对上面的代码进行一点修改:

1 from celery import group
2 from CelerySpider.test import add
3
4
5 lazy_group = group(add.s(x, y) for x, y in zip([1, 3, 5, 7, 9], [2, 4, 6, 8, 10]))
6 result = lazy_group()
7 print(result)
8 print(result.get())

  运行之后得到了我们想要的结果:

f03387f1-af00-400b-b58a-37901563251d

[3, 7, 11, 15, 19]

2.celer.result.collect()

  在Celery中有一个类result,这个类包含了任务运行的结果和状态等,而在这个类中就有一个collect()方法,使用该方法能在结果返回时收集结果。和之前一样的步骤,先看看源码:

  

  这里看源码也是看得一头雾水,不如动手写代码试试看。创建一个app.py,其中代码如下:

 1 from celery import Celery, group, result
 2
 3
 4 app = Celery("test", broker="redis://127.0.0.1:6379", backend="redis://127.0.0.1:6379")
 5
 6
 7 @app.task(trail=True)
 8 def A(how_many):
 9     return group(B.s(i) for i in range(how_many))()
10
11
12 @app.task(trail=True)
13 def B(i):
14     return pow2.delay(i)
15
16
17 @app.task(trail=True)
18 def pow2(i):
19     return i ** 2
20
21
22 if __name__ == '__main__':
23     app.start()

  可以看到在设置任务的时候都加了参数trail=True,这是为了存储子任务列表运行后的结果,虽然是默认设置,但这里明确启用。在运行Celery服务器之中,进入app.py同级目录,输入python,然后执行如下代码:

>>> from app import A
>>> res = A.delay(10)
>>> [i[1] for i in res.collect() if isinstance(i[1], int)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

三、具体步骤

1.项目结构

  这个爬虫项目的基本文件如下:

  

  其中app.py用于创建Celery实例,celeryconfig.py是Celery需要使用的配置文件,tasks.py里面的则是具体的任务,crawl.py是爬虫脚本,在打开Celery服务器之后,运行此文件即可。

2.主要代码

  首先是app.py,代码如下,其中config_from_object()方法用于配置Celery,传入的参数是一个可被导入的模块:

 1 from celery import Celery
 2
 3
 4 app = Celery("spiders", include=["CelerySpider.tasks"])
 5 # 导入配置文件
 6 app.config_from_object("CelerySpider.celeryconfig")
 7
 8
 9 if __name__ == '__main__':
10     app.start()

  下面是tasks.py中的代码,其中包含了发送请求和解析网页的代码:

 1 import requests
 2 from lxml import etree
 3 from celery import group
 4 from CelerySpider.app import app
 5
 6
 7 headers = {
 8     "Cookie": "__cfduid=d5d815918f19b7370d14f80fc93f1f27e1566719058; UM_distinctid=16cc7bba92f7b6-0aac860ea9b9a7-7373e61-144000-16cc7bba930727; CNZZDATA1256911977=1379501843-1566718872-https%253A%252F%252Fwww.baidu.com%252F%7C1566718872; XSRF-TOKEN=eyJpdiI6InJvNVdZM0krZ1wvXC9BQjg3YUk5aGM1Zz09IiwidmFsdWUiOiI5WkI4QU42a0VTQUxKU2ZZelVxK1dFdVFydlVxb3g0NVpicEdkSGtyN0Uya3VkXC9pUkhTd2plVUtUTE5FNWR1aCIsIm1hYyI6Ijg4NjViZTQzNGRhZDcxNTdhMDZlMWM5MzI4NmVkOGZhNmRlNTBlYWM0MzUyODIyOWQ4ZmFhOTUxYjBjMTRmNDMifQ%3D%3D; doutula_session=eyJpdiI6IjFoK25pTG50azEwOXlZbmpWZGtacnc9PSIsInZhbHVlIjoiVGY2MU5Ob2pocnJsNVBLZUNMTWw5OVpjT0J6REJmOGVpSkZwNFlUZVwvd0tsMnZsaiszWEpTbEdyZFZ6cW9UR1QiLCJtYWMiOiIxZGQzNTJlNzBmYWE0MmQzMzQ0YzUzYmYwYmMyOWY3YzkxZjJlZTllNDdiZTlkODA2YmQ3YWRjNGRmZDgzYzNmIn0%3D",
 9     "Referer": "https://www.doutula.com/article/list/?page=1",
10     "UserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
11 }
12
13
14 @app.task(trail=True)
15 def main(urls):
16     # 主函数
17     return group(call.s(url) for url in urls)()
18
19
20 @app.task(trail=True)
21 def call(url):
22     # 发送请求
23     try:
24         res = requests.get(url, headers=headers)
25         parse.delay(res.text)
26     except Exception as e:
27         print(e)
28
29
30 @app.task(trail=True)
31 def parse(html):
32     # 解析网页
33     et = etree.HTML(html)
34     href_list = et.xpath('//*[@id="home"]/div/div[2]/a/@href')
35     result = []
36     for href in href_list:
37         href_res = requests.get(href, headers=headers)
38         href_et = etree.HTML(href_res.text)
39         src_list = href_et.xpath('//*[@class="artile_des"]/table/tbody/tr/td/a/img/@src')
40         result.extend(src_list)
41     return result

  最后是crawl.py中的代码:

 1 import time
 2 from CelerySpider.tasks import main
 3
 4
 5 start_time = time.time()
 6
 7
 8 url_list = ["https://www.doutula.com/article/list/?page={}".format(i) for i in range(1, 31)]
 9 res = main.delay(url_list)
10 all_src = []
11 for i in res.collect():
12     if isinstance(i[1], list) and isinstance(i[1][0], str):
13         all_src.extend(i[1])
14
15 print("Src count: ", len(all_src))
16
17
18 end_time = time.time()
19 print("Cost time: ", end_time - start_time)

  此次爬取的网站是一个表情包网站,url_list就表示要爬取的url,这里我选择爬取30页来测试。all_src用于存储表情包图片的资源链接,通过collect()方法提取出要爬取的链接,然后将这些表情包下载下来,最后打印出下载的图片数量和整个程序所耗费的时间。

四、运行结果

  当运行Celery服务后,再运行crawl.py文件,会看到如下信息打印出来:

  

  当整个爬虫运行完毕后,会打印出所耗费的时间:

  

  完整代码已上传到GitHub!

转载于:https://www.cnblogs.com/TM0831/p/11405077.html

【Python3爬虫】快就完事了--使用Celery加速你的爬虫相关推荐

  1. python如何爬取网页视频_快就完事了!10分钟用python爬取网站视频和图片

    原标题:快就完事了!10分钟用python爬取网站视频和图片 话不多说,直接开讲!教你如何用Python爬虫爬取各大网站视频和图片. 638855753 网站分析: 我们点视频按钮,可以看到的链接是: ...

  2. python3 爬虫 requests安装_BOSS直聘招聘信息获取之爬虫工具分析

    点击蓝色"不太灵光的程序员"关注我哟 加个"星标",每天上午 09:30,干货推送! 文中使用的组件库仅限于Python语言,由于最近收到一些同学的留言说,按照 ...

  3. python3反爬虫原理与绕过实战 网盘_Python 3反爬虫原理与绕过实战

    第 1章 开发环境配置 1 1.1 操作系统的选择 1 1.1.1 Ubuntu 简介 1 1.1.2 VirtualBox 的安装 2 1.1.3 安装 Ubuntu 3 1.1.4 全屏设置 8 ...

  4. 快看这里,豆瓣9.0的Python爬虫宝藏书籍,自学爬虫必备~

    哈喽~大家好!我是恰恰.今天我们来学些什么呢,那就是爬虫啦!说到学习爬虫,相信很多人都是听过一句话,"爬虫爬的好,监狱进的早"!虽然有点夸张的感觉,但是这也侧面说明,如果学会了爬虫 ...

  5. 爬虫分页爬取猎聘_想把python爬虫了解透彻吗?一起盘它 ! !

    原理 传统的爬虫程序从初始web页面的一个或多个url开始,并获取初始web页面的url.在抓取web页面的过程中,它不断地从当前页面中提取新的url并将其放入队列中,直到满足系统的某些停止条件.聚焦 ...

  6. 网络爬虫python的特点有哪些_为什么写网络爬虫天然就是择Python而用

    关于这个问题,老猿就先从自己的经历讲起吧.很多年前,大约11年前,老猿我接手了一个搜索引擎的网络爬虫,那是一个用C++写的通用搜索引擎的爬虫.C++的语言,多线程的实现,爬虫的运行效率非常高.但是,找 ...

  7. python爬虫设计在哪里_《python 爬虫教程 知乎》 怎样用Python设计一个爬虫模拟登陆知乎...

    <python 爬虫教程 知乎> 怎样用Python设计一个爬虫模拟登陆知乎 python 爬虫教程 知乎2020-09-23 01:45:13人已围观 怎样用Python设计一个爬虫模拟 ...

  8. python爬虫工程师需要会什么软件_Python学习教程:爬虫工程师必备的10个爬虫工具!...

    Python学习教程:爬虫工程师必备的10个爬虫工具! 最近很多学爬虫的伙伴让推荐顺手的爬虫工具,南瓜花了点时间总结了一下,把这些好用的爬虫工具都跟你们找齐活了! 都知道工欲善其事必先利其器,那么作为 ...

  9. 为什么用python写爬虫_零基础,是怎么开始写Python爬虫的

    刚开始接触爬虫的时候,简直惊为天人,十几行代码,就可以将无数网页的信息全部获取下来,自动选取网页元素,自动整理成结构化的文件. 利用这些数据,可以做很多领域的分析.市场调研,获得很多有价值的信息.这种 ...

最新文章

  1. 转帖 .Net(C#)纯GDI+绘制实时动态曲线图之二(曲线控件全部源码)
  2. C++创建二维数组和矩阵
  3. boost::math模块使用来自函数调用的常量的测试程序
  4. Java 操作 HDFS
  5. python导入模块以及类_python模块的导入以及模块简介
  6. python word模板 图_科学网—Python绘制可插入Word的高清矢量图(SVG转EMF) - 任晓东的博文...
  7. office2010出现“此错误通常是由宏安全性设置造成的”的解决办法
  8. Java 8 时间日期库的20个使用演示样例
  9. 由浅入深CIL系列:4.抛砖引玉:使用CIL来分析string类型在.NET运算中的性能和避免装箱...
  10. 【元胞自动机】基于matlab元胞自动机交通流仿真【含Matlab源码 827期】
  11. 浪潮之巅 第三章 “水果公司”的复兴 (4) 大难不死
  12. Markdown 语法支持测试
  13. Pandas的基本操作
  14. Linux的目录结构及对应目录下存放的内容
  15. 1068 万绿丛中一点红 Python实现
  16. python之HTML-块级标签
  17. 水果店水果保鲜期延长方法,水果店经营保鲜方法
  18. 敏捷开发松结对编程系列:L型代码结构案例StatusFiltersDropdownList(下)
  19. 设计模式 外观模式 一键电影模式
  20. python基础教程Day04

热门文章

  1. Linux服务器非root用户下安装CUDA11.1和cudnn到指定目录
  2. 深入理解JVM的内存区域划分
  3. python读入txt数据,并转成矩阵
  4. (一)golang工作区
  5. 爬取校园网新闻首页的新闻 使用正则表达式,函数抽离
  6. sed-awk命令详解
  7. Release编译模式下,事件是否会引起内存泄漏问题初步研究
  8. linux 架设J2EE网站过程分享之二 —— JDK安装
  9. 额外sql使用什么封装_为什么建立社区值得付出额外的努力
  10. linux wps2016_2016年排名前7的Linux游戏