需求分析

昨天,我给妹子做了一个爬取头像的爬虫程序,妹子总算是开心起来了,我总算也是松了一口气,然而今天,就接到妹子的投诉了

她说,“你这个程序啊,太慢!爬取一次要花的时间太长!你能不能给改进一下?”

害,这有什么困难的呢?妹子不知道,我在程序中加了time.sleep(),只需要把time.sleep()删除掉,速度就加快了。不过呢,这样做虽然有效,但是毕竟能够加快的速度有限。如果我们希望更快,就得升级到多线程的爬虫程序,下面就来试试看吧

实现分析

首先呢,我们需要知道在python中如何实现多线程,这个其实很简单,只需要使用threading就可以了

from threading import Thread
import timedef thread_test():for i in range(10):print(i)time.sleep(1)# 启动一个线程,让该线程执行target指定的任务
t = Thread(target=thread_test)
t.start()

线程之间是可以共享全局变量的,但是如果同时对全局变量进行修改的话,可能就会出现一些问题,因此,在爬虫中使用的话,我们不能够直接通过list保存地址,然后通过线程去list中取得地址,这样会由于同时对列表进行操作,而产生冲突。冲突了以后自然就会导致结果不正确

因此,在线程的使用中,我们可以考虑通过queue来完成爬虫任务,首先启动一个线程,把爬取到的图片地址加入到queue中,然后再启动多个线程,去爬取queue中保存的图片地址,以此来实现多线程的爬虫程序,大致结构就像这样

from threading import Thread
from queue import Queue
import timeq = Queue()def put():for i in range(30):time.sleep(0.2)q.put(i)def get():while True:print(q.get())time.sleep(1)t = Thread(target=put)
t.start()t1 = Thread(target=get)
t2 = Thread(target=get)
t1.setDaemon(True)
t2.setDaemon(True)
t1.start()
t2.start()time.sleep(20)

完整代码实现

import requests
import time
from base64 import b64decode
from lxml import etree
from threading import Thread
from queue import Queueurl_queue = Queue() headers = {"user-agent": "Mozilla/5.0"}
url = b64decode("aHR0cDovL3d3dy5pbWVpdG91LmNvbS9kb25nbWFuLw==").decode()r = requests.get(url, headers=headers)
r.encoding = "gb2312" html = etree.HTML(r.text)urls = html.xpath("//ul[@class='g-gxlist-imgbox']//li/a/@href")
titles = html.xpath("//ul[@class='g-gxlist-imgbox']//li/a/@title")def get_urls(): num = 1for i in range(len(urls)):url = urls[i]r = requests.get(url, headers=headers)r.encoding = "gb2312"html = etree.HTML(r.text)img = html.xpath("//div[@class='img-list3']//img/@src")for u in img:name = str(num) + ".png"url_queue.put({"name": name, "url": u})num += 1time.sleep(1)def get_img():while True:u = url_queue.get()url = u["url"]name = u["name"]r = requests.get(url, headers=headers)with open(name, "wb") as f:f.write(r.content)time.sleep(1)url_queue.task_done()def get_info():while True:time.sleep(10)print("目前还剩下" + str(url_queue.qsize()) + "个头像未完成")def run(num):if num > 4:num = 4tu = Thread(target=get_urls)tu.start()ti = Thread(target=get_info)ti.setDaemon(True)ti.start()ts = []for i in range(num):t = Thread(target=get_img)t.setDaemon(True)ts.append(t)for t in ts:t.start()tu.join()while True:n = input("你希望每秒能爬几张头像:")try:run(int(n))url_queue.join()breakexcept:continue

程序运行效果展示,可以看到,由于是多线程的程序,添加待爬取的头像和爬取头像分别是由不同的线程完成的,因此在剩余数量上就可能出现有时上升,有时下降的情况。添加待爬取的头像的线程工作的快一些,那么剩余的头像数量就会增多,爬取头像的线程工作快一些,那么剩余的头像数量就会减少

很快,我们就可以看到我们的头像图片已经成功的爬取完成了​​​​​​​,运行程序即可查看结果


注意!虽然我的程序是多线程的程序,而制作多线程程序当然也是为了能够更快爬取,但是我个人是不建议你这样做的。爬取速度太快会给对方网站带来很大的压力,这是很不道德的行为,如果有可能的话,请尽量保持发送请求的间隔时间在1秒以上!

妹子说头像爬的太慢?升级到多线程程序爬取头像相关推荐

  1. 爬取头像的程序不好用了?那就再重新做一份咯

    需求分析 今天,突然有一个粉丝找到我说,"仙草哥哥,今天是开学的第一天,有一句话怎么说的来着,新学期,新气象,我也想换一个新头像.但是呢,之前你那个爬取头像的程序,不知道为什么不能用了,现在 ...

  2. 热血动漫番太好看了!用Python爬取了1T的动漫,内存都爆了

    大家好,我是辣条. 最近被室友安利热血动漫番<终末的女武神>和<拳愿阿修罗>,太上头了周末休息熬夜看完了.不过资源不太好找,辣条一怒爬取了资源,这下可以看个够了.室友崇拜连连, ...

  3. 简单爬虫爬取头像,妈妈再也不用担心我头像不够用了

    目标网站 如题,实现头像的爬取,我们先找我们需要爬取的网站:图片_朋友圈背景图_好看的图片_我要个性网 (woyaogexing.com) 我们再简单了解一下,爬虫,在我学习到目前浅浅的理解是,让爬虫 ...

  4. 一堆让人激动的头像生成器,太香了!-搜嗖工具箱

    GeneratedPhotos https://generated.photos/face-generator 这个网站可以通过AI智能生成真人头像,网站有两百多万张,这些人在现实生活中并不存在,生成 ...

  5. python3爬虫实战:requests库+正则表达式爬取头像

    python3爬虫实战:requests库+正则表达式爬取头像 网站url:https://www.woyaogexing.com/touxiang/qinglv/new/ 浏览网页:可以发现每个图片 ...

  6. 程序员微信头像_微信头像暴露了你的层次:层次越低的人,越喜欢用这些头像...

    这个话题,原本很轻松.但往细里看,它背后玄机很多.许多未知理论与认知可能性,往往就在不为人知的拐角处. 卞之琳有一首诗:你站在桥上看风景,看风景的人在楼上看你.明月装饰了你的窗子,你装饰了别人的梦.此 ...

  7. ios 刷新头像_想请问各位大大,iOS中新旧头像缓存的策略是什么?如微信,每次更换个人头像后,服务器怎么处理新旧头像?...

    新旧头像如何处理,需要考虑服务端和客户端两个方面. 通常大公司会将文件上传做成基础服务,跟特定的应用无关.假设这里,文件上传为服务 A, 特定的应用为服务 B,客户端为 C.这时候替换头像大致有两种做 ...

  8. 第一次写爬虫程序爬取豆瓣5W条电影数据

    第一次写爬虫程序爬取豆瓣5W条电影数据 最近工作比较不是很忙,想到之前使用httpclient和jsoup爬取过一次豆瓣电影TOP250,但总觉得数据量太小,不过瘾.于是趁着最近不是很忙的机会,重新写 ...

  9. android ui头像圆角化,APP界面设计当中,为什么喜欢把头像设计成圆形

    看到这样的标题,你是不是也很惊奇呢?仔细的去回想一下,好像很多APP界面设计当中的头像都是圆形的.很少见到头像是方形的.菱形或者四边形的. 这是为什么呢? 难道是因为好看吗? 今天25学堂的小编跟大家 ...

最新文章

  1. mysql中日志的特点_mysqlbinlog的日志类型
  2. Java程序员必看!2021最新爱奇艺Java社招面试题目
  3. 导航栏中加入自动弹出下拉菜单
  4. 无脑博士的试管们java_计蒜客 无脑博士和他的试管们
  5. Java并发包--阻塞队列(BlockingQueue)
  6. ASP.NET 2.0:如何让DropDownList同时拥有数据来源项目与自订项目 (转自章立民CnBlogs)...
  7. OA项目10:部门管理的三个细节问题的解决及处理懒加载问题
  8. 微软推出了一款能帮你“做题”的数学应用
  9. maftools|TCGA肿瘤突变数据的汇总,分析和可视化
  10. 风控人最容易被误解的一个风险管理板块
  11. 11 个问题,帮你彻底搞懂工业互联网
  12. JAVA基础--toString, equals方法
  13. 深入解析 Flink 细粒度资源管理
  14. at()函数遍历图像
  15. Unity上传图片到服务器及服务器如何配置
  16. 计算机网络 latency,网络中delay和latency的区别
  17. 【数据结构】链表 - Go 语言实现
  18. 统计学中基础概念说明
  19. UE4 材质笔记之墙面(纹理混合+顶点颜色应用)
  20. 马斯克中止推特收购,分手费10亿美元

热门文章

  1. SEO的道与术,因果关系的选择
  2. 【转】胡侃学习(理论)计算机
  3. nodejs+koa2实现微信小程序签名和请求支付(二)
  4. 5G到底什么时候来,以及,它究竟能给我们带来什么?
  5. outlook配置阿里企业邮箱
  6. jQuery uploadify 文件上传
  7. 亲情的矛盾都是因为爱而化解 写给17 岁的你
  8. 视频教程-微信小程序快速入门视频课程-微信开发
  9. Android判断用户是否已完成设置向导(开机向导)
  10. PCM设备的E1接头