Python批量从IPFS下载图片循环报错、单条正常该如何解决?
错误原因
- 请求触发公共网关限流:ipfs.io公共网关存在请求频率限制,短时间连续发起大量请求会被服务端主动断开连接,单请求可正常运行就是该机制导致的。
- 数据读取逻辑错误:你定义的链接列表第一行为表头,但初始化DataFrame时未将其设为列名,且后续读取字段时大小写不匹配,导致拿到的
link、num变量为空,也会引发请求异常。
修正后完整代码
import time import random import pandas as pd import urllib.request from urllib.error import URLError # 初始化数据,将第一行设为表头 links = [['number', 'link'], ['0', 'https://ipfs.io/ipfs/QmRRPWG96cmgTn2qSzjwr2qvfNEuhunv6FNeMFGa9bx6mQ'], ['1', 'https://ipfs.io/ipfs/QmPbxeGcXhYQQNgsC6a36dDyYUcHgMLnGKnF8pVFmGsvqi'], ['2', 'https://ipfs.io/ipfs/QmcJYkCKK7QPmYWjp4FD2e3Lv5WCGFuHNUByvGKBaytif4'], ['3', 'https://ipfs.io/ipfs/QmYxT4LnK8sqLupjbS6eRvu1si7Ly2wFQAqFebxhWntcf6'], ['4', 'https://ipfs.io/ipfs/QmSg9bPzW9anFYc3wWU5KnvymwkxQTpmqcRSfYj7UmiBa7'], ['5', 'https://ipfs.io/ipfs/QmNwbd7ctEhGpVkP8nZvBBQfiNeFKRdxftJAxxEdkUKLcQ'], ['6', 'https://ipfs.io/ipfs/QmWBgfBhyVmHNhBfEQ7p1P4Mpn7pm5b8KgSab2caELnTuV'], ['7', 'https://ipfs.io/ipfs/QmRsJLrg27GQ1ZWyrXZFuJFdU5bapfzsyBfm3CAX1V1bw6']] data = pd.DataFrame(links[1:], columns=links[0]) # 伪装浏览器请求头,避免被网关识别为爬虫 opener = urllib.request.build_opener() opener.addheaders = [('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36')] urllib.request.install_opener(opener) # 循环下载 for index, row in data.iterrows(): num = row['number'] url = row['link'] filename = f"{num}.png" max_retry = 3 retry_count = 0 # 重试逻辑 while retry_count < max_retry: try: urllib.request.urlretrieve(url, filename) print(f"编号{num}下载完成") # 随机等待1-3秒,降低请求频率 time.sleep(random.uniform(1,3)) break except URLError as e: retry_count += 1 print(f"编号{num}第{retry_count}次下载失败,错误:{e},等待2秒后重试") time.sleep(2) if retry_count == max_retry: print(f"编号{num}下载失败,已达到最大重试次数")
核心优化说明
- 修正了DataFrame初始化逻辑,将第一行内容设为列名,保证可以正常读取编号和链接字段
- 添加了浏览器UA伪装,降低被网关识别为爬虫的概率
- 每次下载完成后加入1-3秒的随机等待,避免触发网关频率限制
- 增加了失败重试机制,单次请求失败后等待2秒再重试,最多重试3次,避免偶发网络波动导致任务中断
内容的提问来源于stack exchange,提问作者Technaut
相关产品推荐
相关产品推荐

