在使用 python 协程下载图片中,最终协程的任务数卡在 97 一直循环,不知道哪里出了问题,有大佬知道什么情况吗,困扰我好久

这个是运行的结果,在任务数为 80 一直卡着

队列是否为空.... 80

队列是否为空.... 80

.

.

.

队列是否为空.... 80

队列是否为空.... 80

下面贴上代码

from lxml import etree

import os

import pandas as pd

import asyncio

import aiohttp

from random import randint

import cchardet

import aiofiles

import logging

class sikupicture_Spider(object):

def __init__(self):

# self.seens_url = []

self.loop = asyncio.get_event_loop()

self.queue = asyncio.PriorityQueue()

self._workers = 0 # 当前工作数

self._max_workers = 150 # 最大工作数

self.overtime = {} # {url: times,} 记录失败的 URL 的次数

self.overtime_threshold = 4

self.headers = {

"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",

}

self.list_content = []

async def init_url(self):

info = pd.read_excel(r"{}".format(os.path.abspath('moban.xlsx'))).fillna('')

for ite in info.itertuples():

await self.queue.put((randint(1, 5), getattr(ite, 'url')))

async def fetch(self, session, url, timeout, headers=None, binary=False, proxy=None):

_headers = self.headers

if headers:

_headers = headers

try:

async with session.get(url, headers=_headers, timeout=timeout, proxy=proxy, allow_redirects=False) as resp:

status_code = resp.status

if status_code == 403:

print("url-403", url)

if url in self.overtime:

self.overtime[url] += 1

if self.overtime[url] > self.overtime_threshold:

pass

await self.queue.put((randint(1, 5), url))

else:

self.overtime[url] = 1

await self.queue.put((randint(1, 5), url))

status_code = 0

html = None

if binary:

text = await resp.read()

encoding = cchardet.detect(text)

html = text.encode(encoding, errors='ignore')

else:

html = await resp.text()

except TimeoutError:

print("url-overtime", url)

if url in self.overtime:

self.overtime[url] += 1

if self.overtime[url] > self.overtime_threshold:

pass

await self.queue.put((randint(1, 5), url))

else:

self.overtime[url] = 1

await self.queue.put((randint(1, 5), url))

status_code = 0

html = None

return status_code, html

async def download_img(self, session, img_url, timeout, url, headers=None, binary=True, proxy=None):

_headers = self.headers

if headers:

_headers = headers

try:

async with session.get(img_url, headers=_headers, timeout=timeout, proxy=proxy, allow_redirects=False) as resp:

status_code = resp.status

if binary:

html = await resp.read()

else:

html = await resp.text()

except TimeoutError:

print("url-overtime", img_url)

if url in self.overtime:

self.overtime[url] += 1

if self.overtime[url] > self.overtime_threshold:

pass

else:

await self.queue.put((randint(1, 5), url))

else:

self.overtime[url] = 1

await self.queue.put((randint(1, 5), url))

status_code = 0

html = None

return status_code, html

def parse_source(self, source):

try:

response_1 = etree.HTML(source)

except Exception as err:

logging.error(f'parse error:{err}')

url = ""

else:

img_url = response_1.xpath("//a[@href='javascript:;']/@supsrc")[0] if len(

response_1.xpath("//a[@href='javascript:;']/@supsrc")[0]) else ""

return img_url

async def process(self, session, url, timeout):

status, source = await self.fetch(session, url, timeout)

file_name = url.replace("http://item.secoo.com/", "").replace(".shtml", "")

if status == 200:

img_url = self.parse_source(source)

img_status, img_source = await self.download_img(session, img_url, timeout, url)

if img_status == 200:

async with aiofiles.open("F:\\dawnzhu\\picture\\"+file_name+".jpg", "wb") as f:

await f.write(img_source)

self._workers -= 1

print("任务完成", self._workers, "url_status", status, "img_status", img_status)

else:

self._workers -= 1

print("任务完成", self._workers, "url_status", status,)

async def loop_crawl(self):

await self.init_url()

timeout = aiohttp.ClientTimeout(total=20)

conn = aiohttp.TCPConnector(loop=self.loop, limit=50, force_close=True, enable_cleanup_closed=True)

session = aiohttp.ClientSession(connector=conn, timeout=timeout)

while True:

if self._workers >= self._max_workers:

print("work 的判断")

await asyncio.sleep(5)

continue

if self.queue.empty():

print("队列是否为空....", self._workers)

await asyncio.sleep(5)

if self._workers == 0:

break

continue

_, url = await self.queue.get()

asyncio.ensure_future(self.process(session, url, timeout))

self._workers += 1

print("队列剩余数量", self.queue.qsize(), self._workers)

await session.close()

def run(self):

try:

self.loop.run_until_complete(self.loop_crawl())

except KeyboardInterrupt:

self.loop.close()

if __name__ == '__main__':

sp = sikupicture_Spider()

sp.run()

python3.6.2卡住_Python 协程任务卡住不动相关推荐

  1. python 协程 php,python3.x,协程_python协程练习部分代码的理解?,python3.x,协程,asyncio - phpStudy...

    python协程练习部分代码的理解? import asyncio import threading async def wget(host): print('wget {}'.format(host ...

  2. python gevent模块 下载_Python协程阻塞IO非阻塞IO同步IO异步IO

    Python-协程-阻塞IO-非阻塞IO-同步IO-异步IO 一.协程 协程又称为微线程 CPU 是无法识别协程的,只能识别是线程,协程是由开发人员自己控制的.协程可以在单线程下实现并发的效果(实际计 ...

  3. python 协程_Python 协程与 Go 协程的区别(一)

    ? "Python猫" ,一个值得加星标的公众号 花下猫语:年关将近,不知各位过得怎样?我最近有些忙,收获也挺多,以后有机会分享下.吃饭时间,追了两部剧<了不起的麦瑟尔夫人& ...

  4. python中协程与函数的区别_python 协程与go协程的区别

    进程.线程和协程 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定义: 操作系统能够进行运算调度的最小单位.它被包含在进 ...

  5. python 协程和异步的关系_python协程与异步协程

    在前面几个博客中我们一一对应解决了消费者消费的速度跟不上生产者,浪费我们大量的时间去等待的问题,在这里,针对业务逻辑比较耗时间的问题,我们还有除了多进程之外更优的解决方式,那就是协程和异步协程.在引入 ...

  6. python协程实时输出_python协程

    不知道你有没有被问到过有没有使用过的python协程? 协程是什么? 协程是一种用户态轻量级,是实现并发编程的一种方式.说到并发,就能想到了多线程 / 多进程模型,是解决并发问题的经典模型之一. 但是 ...

  7. python协成_Python协程(上)

    几个概念: event_loop 事件循环:程序开启一个无限的循环,程序员会把一些函数注册到事件循环上.当满足事件发生的时候,调用相应的协程函数. coroutine 协程:协程对象,指一个使用asy ...

  8. python协成_Python协程技术的演进

    引言 1.1. 存储器山 存储器山是 Randal Bryant 在<深入理解计算机系统>一书中提出的概念. 基于成本.效率的考量,计算机存储器被设计成多级金字塔结构,塔顶是速度最快.成本 ...

  9. python从零开始到放弃_Python 协程从零开始到放弃

    0x00 前言 很久以前就听说 Python 的 async/await 很厉害,但是直到现在都没有用过,一直都在用多线程模型来解决各种问题.最近看到隔壁的 Go 又很火,所以决定花时间研究下 Pyt ...

最新文章

  1. c 宏定义用法#define
  2. vba 修改access表的链接地址_VBA中常用的这7种数据类型,你都get到了吗?
  3. “你不明白欣德利 - 米尔纳的哪一部分?”
  4. mapreduce编程实例python-Python模拟MapReduce的流程
  5. 计算机版本号怎么看,怎样查看电脑版本型号,怎样查看电脑版本信息
  6. 20165220 第七周学习总结
  7. jquery 获得鼠标指针 X/Y 值
  8. uboot-spl编译流程
  9. java dbtype_Java实现数据库的读写分离
  10. 1001: [BeiJing2006]狼抓兔子
  11. (个人总结)Linux命令——任意目录查看穿越
  12. 操作系统进程调度先来先服务FCFS
  13. 英语口语Week16 Thursday
  14. Windows中,文件所在路径查找命令
  15. python自动化办公excel-Python自动化办公之操作Excel文件
  16. Python入门--列表元素的判断及遍历,判断指定元素在列表中是否存在,列表元素的遍历,
  17. ans函数python_#12 Python函数
  18. mysql 触发器 实例_MySQL触发器简单用法示例
  19. c语言空字符和 0 的区别,C语言'\0'、'0'、' '、“0”、0的区别详解
  20. [Linux系统编程/网络编程] 笔记目录

热门文章

  1. JS脚本调起小狐狸MetaMask浏览器扩展插件解锁
  2. 案例1(段落分段,锚点连接,插入图片,路径使用,外部链接,文字加粗)
  3. List集合的交集(retainAll)、并集(removeAll,addAll)、差集(removeAll)
  4. NLP输出文本评估:使用BLEU需要承担哪些风险?
  5. 基于C++的简易中文输入法
  6. 不义联盟网站无法连接服务器,不义联盟:人间之神无法连接服务器是什么原因...
  7. elementUI 框架组件
  8. python爬取天气预报用163邮箱发
  9. android 连接隐藏wifi,小技能 | 教你如何连接隐藏了的wifi(最齐全版本)
  10. 智力题—从三箱水果里取一个,判断哪个箱子里装的是什么水果