urllib2下载的.jpg文件损坏导致FPDF无法生成PDF的问题求助
解决JPG下载损坏导致FPDF生成失败的问题
我之前也碰到过类似的情况,这种半灰色的损坏图片大概率是下载过程中数据不完整、请求被服务器限流,或者文件写入方式不对导致的。结合你给出的代码片段,咱们来一步步解决:
1. 修复文件写入模式(最可能的直接原因)
你当前用的是'w'文本模式写入文件,但JPG是二进制格式,文本模式会自动转换换行符,直接破坏二进制数据。必须改用二进制写入模式'wb':
filename = ''.join(pageForFilename) add_image_to_list() # 把'w'改成'wb' file_ = open(filename, 'wb') file_.write(data) file_.close() time.sleep(0.5)
这一步解决了很多因为编码导致的文件损坏问题,先优先改这个。
2. 添加重试机制,应对服务器限流/连接中断
每下载20个左右就出问题,很可能是服务器识别到频繁请求,开始限流(返回不完整数据)。给下载逻辑加个重试机制,比如失败后重试3次,每次间隔递增:
import urllib2 import time def download_image(url, max_retries=3): retries = 0 while retries < max_retries: try: response = urllib2.urlopen(url) # 检查响应状态码,确保请求成功 if response.getcode() != 200: raise Exception(f"请求失败,状态码:{response.getcode()}") data = response.read() return data except Exception as e: print(f"下载失败,重试第{retries+1}次:{str(e)}") retries += 1 time.sleep(1 * retries) # 每次重试间隔翻倍,降低被限流概率 return None # 调用示例 data = download_image(target_url) if data: with open(filename, 'wb') as file_: file_.write(data) time.sleep(0.5) else: print(f"多次重试后仍无法下载:{target_url}")
3. 验证下载的图片完整性
下载完成后,用Pillow库检查图片是否能正常解码,避免损坏的文件流入FPDF环节:
from PIL import Image import io def is_valid_image(data): try: img = Image.open(io.BytesIO(data)) img.verify() # 验证图片结构完整性 return True except (IOError, SyntaxError) as e: print(f"图片损坏:{str(e)}") return False # 下载后验证再保存 data = download_image(target_url) if data and is_valid_image(data): with open(filename, 'wb') as file_: file_.write(data) else: print(f"无效图片,跳过:{target_url}")
4. 优化请求间隔,降低被限流的概率
固定的0.5s间隔可能太规律,容易被服务器识别为爬虫。可以改成随机间隔:
import random # 替换原来的time.sleep(0.5) time.sleep(random.uniform(0.5, 2.0)) # 随机等待0.5到2秒,模拟人类访问节奏
总结
先改写入模式为'wb',这是最基础的错误;然后加上重试和状态码检查,解决服务器限流问题;最后用Pillow验证图片,确保只有有效图片进入PDF生成环节。这样应该就能解决你碰到的半灰色损坏文件问题了。
内容的提问来源于stack exchange,提问作者squ1dd13
相关产品推荐
相关产品推荐

