python 批量下载图片(协程)

要下载的图片网站

 1、总共多少页,得到每页的 url 列表

 

2、每页的图片详情的 ulr 列表(因为该高清大图在图片详情页,因此需要去图片详情页拿图片的url)

​​​​​​​

 

 

3、进入图片详情页,获取到图片url 然后下载。

 

完整代码如下:

import
<think>好的,用户让我详细讲解Python协程。首先,我需要回忆协程的基本概念,以及它在Python中的发展历程。协程是轻量级的线程,用于异步编程,对吧?Python中从生成器开始,通过yield关键字逐步演化到async和await语法。可能需要先解释生成器如何演变成协程,然后介绍asyncio库。 用户可能已经了解生成器,但不确定,所以需要从基础讲起。应该分步骤讲解,比如先讲生成器与协程的关系,再引入async/await,最后讲实际应用和示例代码。同时要注意代码的正确性,确保示例能运行,比如用async def定义协程函数,用await调用其他协程。 另外,用户可能需要知道协程的优势,比如非阻塞IO操作、高并发处理。这时候需要对比多线程和多进程,说明协程在IO密集型任务中的高效性。还要提到事件循环的概念,因为asyncio的核心就是事件循环管理协程的执行。 可能还需要注意Python的版本问题,比如async和await在Python 3.5之后引入,之前版本可能用@asyncio.coroutine装饰器和yield from。但现在的标准写法是async/await,所以应该以新语法为主。 用户可能会对如何使用协程处理实际任务感兴趣,比如网络请求、文件读写等异步操作。这时候可以举一个使用aiohttp进行异步HTTP请求的例子,或者使用asyncio.gather同时运行多个协程。 还要注意常见的错误和陷阱,比如在协程中不要调用阻塞代码,否则会挂起整个事件循环。应该提醒用户使用异步版本的库,比如aiohttp代替requests。 最后,总结协程的适用场景和最佳实践,帮助用户理解何时使用协程,以及如何有效利用它们提高程序性能。可能还需要提到与其他异步编程模型的对比,比如回调函数和Promise,说明协程在可读性和可维护性上的优势。</think>好的,我将分步骤详细讲解Python协程,并提供易于理解的代码示例: 一、协程的演进历史 1. 生成器阶段(Python 2.5+) ```python def old_coroutine(): while True: received = yield # 暂停执行并接收值 print(f"Received: {received}") coro = old_coroutine() next(coro) # 激活生成器 coro.send("Hello") # 输出:Received: Hello ``` 2. 装饰器阶段(Python 3.4) ```python import asyncio @asyncio.coroutine def py34_coroutine(): yield from asyncio.sleep(1) print("After sleep") ``` 3. 现代语法(Python 3.5+) ```python async def modern_coroutine(): await asyncio.sleep(1) print("Using async/await") ``` 二、协程核心概念 1. 事件循环(Event Loop) ```python async def main(): print("Start") await asyncio.sleep(1) print("End") # 创建事件循环 loop = asyncio.get_event_loop() loop.run_until_complete(main()) ``` 2. 并发执行示例 ```python async def task(name, seconds): print(f"{name} started") await asyncio.sleep(seconds) print(f"{name} completed") async def main(): # 同时运行3个任务 await asyncio.gather( task("Task1", 2), task("Task2", 1), task("Task3", 3) ) # 输出顺序: # Task1 started # Task2 started # Task3 started # Task2 completed (1秒后) # Task1 completed (2秒后) # Task3 completed (3秒后) ``` 三、关键语法解析 1. async def ```python async def fetch_data(): return "data" ``` 2. await ```python async def process(): result = await fetch_data() # 等待其他协程完成 print(result) ``` 四、实际应用场景 1. HTTP请求(使用aiohttp) ```python import aiohttp async def fetch_url(url): async with aiohttp.ClientSession() as session: async with session.get(url) as response: return await response.text() async def main(): html = await fetch_url("https://example.com") print(html[:200]) # 打印前200个字符 ``` 2. 定时任务 ```python async def periodic_task(): while True: print("Heartbeat") await asyncio.sleep(5) async def main(): task = asyncio.create_task(periodic_task()) await asyncio.sleep(15) # 运行15秒 task.cancel() ``` 五、协程与线程对比 | 特性 | 协程 | 线程 | |---------------|---------------------|-------------------| | 内存占用 | 约KB级别 | 约MB级别 | | 切换开销 | 极小(无需系统调度)| 较大(需要内核切换)| | 并发能力 | 数千级 | 数百级 | | 数据共享 | 无需锁机制 | 需要同步机制 | | 适用场景 | IO密集型 | CPU密集型 | 六、最佳实践 1. 避免阻塞操作 ```python async def bad_practice(): # 错误示范:使用同步sleep会阻塞事件循环 time.sleep(1) # ❌ async def good_practice(): await asyncio.sleep(1) # ✅ ``` 2. 错误处理 ```python async def error_prone(): raise ValueError("Oops!") async def main(): try: await error_prone() except ValueError as e: print(f"Caught error: {e}") ``` 七、性能优化技巧 1. 批量创建任务 ```python async def batch_processing(): tasks = [asyncio.create_task(fetch_url(url)) for url in url_list] results = await asyncio.gather(*tasks) ``` 2. 限制并发量 ```python import asyncio from aiostream import stream async def limited_concurrency(): urls = [...] # 1000个URL results = [] async with stream.iterate(urls).map( lambda url: fetch_url(url), task_limit=50 # 同时最多50个请求 ).stream() as s: async for result in s: results.append(result) ``` 八、调试技巧 1. 查看协程状态 ```python async def debug_coroutine(): task = asyncio.current_task() print(f"Task name: {task.get_name()}") print(f"Running? {not task.done()}") ``` 2. 使用调试模式 ```bash PYTHONASYNCIODEBUG=1 python your_script.py ``` 九、常见错误及解决 1. 忘记await ```python async def common_mistake(): # 错误:直接调用协程不会执行 fetch_data() # ❌ 缺少await # 正确 await fetch_data() # ✅ ``` 2. 混合使用同步/异步代码 ```python async def mixed_usage(): # 错误:在协程中直接调用同步IO with open("file.txt") as f: # ❌ content = f.read() # 正确:使用异步文件IO库(如aiofiles) import aiofiles async with aiofiles.open("file.txt") as f: content = await f.read() # ✅ ``` 协程的核心优势在于: - 更高效的IO处理能力 - 更简洁的并发代码结构 - 更低的资源消耗 - 更好的可维护性 实际应用建议: 1. 优先选择支持异步的库(aiohttp替代requests) 2. 合理控制并发数量 3. 使用uvloop提升性能(替代默认事件循环) 4. 结合async/await和传统回调机制 5. 注意协程的生命周期管理 进阶学习方向: - 协程原理(生成器实现细节) - 事件循环底层机制 - asyncpg(异步PostgreSQL驱动) - FastAPI(基于协程的Web框架) - WebSocket实时通信应用 - 分布式任务队列(如arq)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值