使用Python或wget爬取30万+HTML文件卡等待响应问题求助
方案1:优化wget参数解决卡住问题
直接给wget添加超时、重试、跳过已下载文件的参数即可实现全自动无人值守下载,完整命令如下:
wget -i links_file.txt -U netscape \ --timeout=15 \ --connect-timeout=5 \ --read-timeout=10 \ -t 3 \ -w 2 \ -c \ --no-clobber
参数说明:
--timeout=15:全局请求超时阈值,单位为秒,可根据服务器响应速度自行调整--connect-timeout=5:TCP连接建立的最大等待时间--read-timeout=10:连接成功后,服务器超过10秒没有返回数据就自动断开-t 3:单个URL最多重试3次,避免无效请求占用资源-w 2:两次重试之间间隔2秒,降低触发服务器反爬的概率-c:开启断点续传,下载中断后重新启动不会从头下载未完成的文件--no-clobber:跳过已经下载完成的文件,重启任务时不会重复下载已经保存的内容
方案2:更稳定的大规模批量下载替代方案
如果wget还是无法满足需求,可以选择以下方案:
异步Python脚本
之前的urllib方案慢是因为同步串行请求,单链接卡住会阻塞整个队列,换成异步并发方案即可:
- 使用
aiohttp库实现异步请求,限制并发数在5~10之间(同域名请求不要太频繁) - 每次请求添加超时控制,下载完成后记录成功/失败的URL,最后统一补下失败的链接
- 示例核心逻辑参考:
import aiohttp import asyncio import os MAX_CONCURRENCY = 8 TIMEOUT = aiohttp.ClientTimeout(total=15) async def download_url(session, url, save_path): if os.path.exists(save_path): return try: async with session.get(url, timeout=TIMEOUT) as resp: if resp.status == 200: content = await resp.text() with open(save_path, 'w', encoding='utf-8') as f: f.write(content) except Exception as e: # 可以把失败的url写入单独的文件后续补下 with open('failed_urls.txt', 'a') as f: f.write(url+'\n') async def main(url_list): connector = aiohttp.TCPConnector(limit=MAX_CONCURRENCY) async with aiohttp.ClientSession(connector=connector) as session: tasks = [] for i, url in enumerate(url_list): save_path = f"./pages/{i}" tasks.append(download_url(session, url, save_path)) await asyncio.gather(*tasks) if __name__ == "__main__": with open('links_file.txt', 'r') as f: url_list = [line.strip() for line in f if line.strip()] asyncio.run(main(url_list))
使用aria2下载工具
aria2是轻量级的跨平台下载工具,支持多链接批量下载、自动重试、断点续传,相比wget对大规模批量下载的容错性更高,核心命令参考:
aria2c -i links_file.txt --user-agent="netscape" --timeout=15 --max-tries=3 --retry-wait=2 --max-concurrent-downloads=8 --continue=true
注意事项
- 同域名批量下载建议控制并发数和请求间隔,避免触发服务器的限流、反爬策略,也避免对目标服务器造成过大压力
- 可以定期备份已下载的文件列表,避免任务异常导致数据丢失
内容的提问来源于stack exchange,提问作者Tobi
相关产品推荐
相关产品推荐

