求助:使用BeautifulSoup爬虫下载的XKCD图片全部损坏
求助:XKCD漫画下载后全部损坏,代码可运行但图片无法正常打开?
我现在急得抓头!跟着书上的练习写了个批量下载XKCD漫画的脚本,代码能跑起来,也确实会往文件夹里塞文件,但所有下载的图片都是损坏的——根本打不开。我完全是按步骤来的,实在摸不着头脑到底哪错了,求各位大佬帮忙排查下!
附上我目前写的代码(好像没贴全,后半段不小心截掉了):
#! python3 # downloadXkcd.py - Downloads every single XKCD comic. import requests, os, bs4 url = 'http://xkcd.com' os.makedirs('xkcd', exist_ok=True) while not url.endswith('#'): # Download the page. print('Downloading page %s......'
大概率的问题点&修复方案
从XKCD下载脚本的常见坑来看,你遇到的图片损坏问题,90%是这两个原因:
- 下载图片时用了文本模式写入,而不是二进制模式
图片是二进制文件,如果你用open(file, 'w')而不是open(file, 'wb')来写,就会破坏文件结构,导致损坏。 - 没有正确获取图片的完整URL,或者没检查请求是否成功
XKCD的漫画图片src是相对路径,得拼接成完整URL;另外没加res.raise_for_status()的话,就算请求失败(比如404)你也不知道,会把错误页面的HTML当成图片存下来,自然打不开。
补全并修复后的完整代码
你可以参考这个版本,应该能解决问题:
#! python3 # downloadXkcd.py - Downloads every single XKCD comic. import requests, os, bs4 url = 'http://xkcd.com' os.makedirs('xkcd', exist_ok=True) while not url.endswith('#'): # 下载当前页面 print(f'Downloading page {url}......') res = requests.get(url) res.raise_for_status() # 强制检查请求是否成功,失败直接报错 soup = bs4.BeautifulSoup(res.text, 'html.parser') # 定位漫画图片元素 comic_elem = soup.select('#comic img') if not comic_elem: print('⚠️ 没找到这页的漫画图片,跳过') else: # 拼接图片的完整URL comic_url = 'http:' + comic_elem[0].get('src') # 下载图片 print(f'Downloading image {comic_url}......') img_res = requests.get(comic_url) img_res.raise_for_status() # 用二进制模式写入文件,避免损坏 img_path = os.path.join('xkcd', os.path.basename(comic_url)) with open(img_path, 'wb') as img_file: for chunk in img_res.iter_content(100000): img_file.write(chunk) # 获取上一页的链接,循环直到最后一页 prev_link = soup.select('a[rel="prev"]')[0] url = 'http://xkcd.com' + prev_link.get('href') print('🎉 所有漫画下载完成!')
内容的提问来源于stack exchange,提问作者BluHaz
相关产品推荐
相关产品推荐

