Python新手写的壁纸爬虫能运行但速度很慢,如何优化?
我知道命名很烂,轻喷,全靠字典直译的! 弄了两个小时才弄出来个 gist 链接,第一次用,凑合看吧
https://gist.github.com/snake1080/817242ef0c0828d7eb3c20692ec2b2c1
Python新手写的壁纸爬虫能运行但速度很慢,如何优化?
多线程并发
你这个爬虫慢,八成是网络请求和同步下载的锅。我直接给你个用 aiohttp 和 asyncio 改的异步版本,速度能快一个数量级。
import aiohttp
import asyncio
import os
from urllib.parse import urljoin
async def download_image(session, url, save_path):
"""异步下载单张图片"""
try:
async with session.get(url) as response:
if response.status == 200:
content = await response.read()
with open(save_path, 'wb') as f:
f.write(content)
print(f"下载成功: {save_path}")
else:
print(f"下载失败,状态码: {response.status}")
except Exception as e:
print(f"下载出错 {url}: {e}")
async def main(base_url, page_count, save_dir):
"""主异步函数"""
os.makedirs(save_dir, exist_ok=True)
# 创建异步会话,设置连接池限制避免被封
connector = aiohttp.TCPConnector(limit=10)
async with aiohttp.ClientSession(connector=connector) as session:
tasks = []
for page in range(1, page_count + 1):
# 这里替换成你实际的页面URL构造逻辑
page_url = f"{base_url}/page/{page}"
try:
async with session.get(page_url) as response:
if response.status == 200:
html = await response.text()
# 这里替换成你实际的图片链接提取逻辑
# 示例:假设从HTML中提取了图片链接列表
image_urls = extract_image_urls(html)
for i, img_url in enumerate(image_urls):
# 构造完整URL
full_url = urljoin(base_url, img_url)
# 生成保存路径
filename = f"page{page}_img{i}.jpg"
save_path = os.path.join(save_dir, filename)
# 创建下载任务
task = asyncio.create_task(
download_image(session, full_url, save_path)
)
tasks.append(task)
else:
print(f"页面请求失败: {page_url}")
except Exception as e:
print(f"页面处理出错 {page_url}: {e}")
# 并发执行所有下载任务
await asyncio.gather(*tasks)
def extract_image_urls(html):
"""从HTML中提取图片链接(需要根据实际网站结构调整)"""
# 这里只是个示例,你需要用BeautifulSoup或正则表达式替换这部分
# 示例:假设图片链接在<img src="...">标签中
import re
return re.findall(r'<img[^>]+src="([^">]+)"', html)
if __name__ == "__main__":
# 配置参数
BASE_URL = "https://example.com/wallpapers" # 替换成目标网站
PAGE_COUNT = 5 # 要爬取的页数
SAVE_DIR = "./wallpapers" # 保存目录
# 运行异步主函数
asyncio.run(main(BASE_URL, PAGE_COUNT, SAVE_DIR))
核心改动:
- 异步请求:用
aiohttp替换requests,网络IO不再阻塞。 - 连接池:
TCPConnector(limit=10)控制并发连接数,既提速又防封IP。 - 任务并发:
asyncio.gather同时发起多个下载任务。
你需要改的地方:
BASE_URL:换成目标网站。extract_image_urls函数:用你的解析逻辑(比如BeautifulSoup)替换我的简单正则。- 页面URL构造逻辑(
page_url)和图片URL处理逻辑。
一句话总结:换异步IO,速度直接起飞。
感觉慢?? debug 下不就知道哪慢了吗
因为发请求的时候没有并发,每一个图片在下载的时候必须要等待上一个图片的下载流程结束
楼主代码太乱了
IO 密集型用多线程
刚接触 python 两三个月,什么是多线程并发?
哈哈哈哈哈,简单看了一下,你的脚本是下完一张图片后才开始下第二张,能不慢么,去看看多线程吧,让他同时多个照片下载
正在搜索什么是 多线程 哈哈
有什么好问的,去补基础
小白多进城 即可
用多线程,顺便再安利一波我的 https://github.com/cwjokaka/bilibili_member_crawler 里面也用了多线程
https://github.com/piglei/one-python-craftsman 再介绍一个别人(大佬)的项目,是关于编码习惯和 python 技巧的。内容很少但很精炼,我也是看完才动手写项目的
2333…一路循环...我看到了我第一次写爬虫时候的风格
只要不怕 IP 被拉黑
多线程 多进程 并发
多谢 正在找多进程的基础教程看
去看看 asyncio 和 asynchttp
刚在我公众号上推了篇文章,讲怎么改你这个代码的,可以看看: https://mp.weixin.qq.com/s/ZDsoEVY0T2GI9E34dkfUZw

