使用Beautiful Soup爬取电影图片时出现0字节文件问题求助
问题分析与解决
你遇到的部分图片下载后为0字节的问题,核心原因是目标网站的反爬机制拦截了你的请求——直接用requests.get()发送请求时,缺少必要的请求头(比如User-Agent),网站会返回空内容而非图片数据;另外还可能存在文件名非法、请求异常未处理的情况。
解决步骤
- 给请求添加浏览器请求头,模拟正常访问
- 检查响应状态码,仅在请求成功(状态码200)时写入文件
- 处理电影名称中的特殊字符(比如冒号、斜杠等),避免文件写入失败
- 添加异常捕获,处理网络请求错误
修改后的代码
import requests from bs4 import BeautifulSoup import pandas as pd import os # 创建必要的文件夹,避免路径不存在报错 os.makedirs("images", exist_ok=True) os.makedirs("Data", exist_ok=True) URL = "https://stacker.com/stories/1587/100-best-movies-all-time" # 模拟浏览器请求头,绕过基础反爬 headers = { "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" } movie_data = [] # 发起页面请求,捕获请求失败情况 page_response = requests.get(URL, headers=headers) page_response.raise_for_status() soap = BeautifulSoup(page_response.text, "html.parser") titles = soap.find_all(name="h2", class_="ct-slideshow__slide__text-container__caption")[1:] description = soap.find_all(name="div", class_="ct-slideshow__slide__text-container__description")[1:] images = soap.find_all(name="img", typeof="foaf:Image")[6:106] for num in range(100): # 处理电影名称,移除多余换行并清理特殊字符 movie_name = titles[num].getText().replace("\n", "").strip() # 替换Windows系统非法文件名字符 safe_filename = movie_name.replace(":", "").replace("/", "-").replace("\\", "-").replace("?", "").replace("*", "").replace('"', "").replace("<", "").replace(">", "").replace("|", "") # 拼接电影描述 local_description = "" local_des = description[num].find_all(name="p")[1:] for s in local_des: local_description += s.getText().replace(" ", "") + "\n" local_description = local_description.strip() movie_data.append({"title": movie_name, "description": local_description}) # 下载图片并处理异常 movie_image_link = images[num].get("src") try: img_response = requests.get(movie_image_link, headers=headers, timeout=10) img_response.raise_for_status() # 检查图片请求是否成功 with open(f"images/{safe_filename}.png", 'wb') as f: f.write(img_response.content) print(f"已完成第 {num+1} 条数据爬取与图片下载") except Exception as e: print(f"第 {num+1} 条图片下载失败: {str(e)}") # 保存数据到CSV data_collected = pd.DataFrame(movie_data) data_collected.to_csv("Data/100_movie.csv", index=False)
关键改进点说明
- 请求头添加:通过
headers传递User-Agent,让请求模拟浏览器访问,避免被基础反爬拦截 - 状态码校验:用
raise_for_status()自动捕获请求失败(如403、500状态码),提前发现问题 - 文件名兼容:替换系统非法字符,避免因文件名无效导致写入失败
- 异常捕获:给图片请求加
try-except块,单个图片下载失败不会中断整个爬取流程 - 文件夹预创建:确保存储目录存在,避免写入时触发路径不存在的错误
内容的提问来源于stack exchange,提问作者user19408629
相关产品推荐
相关产品推荐

