BeautifulSoup爬取谷歌图片重复问题:Colab训练TF模型遇异常
问题分析与解决方案
我来帮你拆解这个问题,你遇到的重复图片问题主要有两个核心原因,咱们一个个说:
1. 谷歌图片的懒加载机制导致你拿到的是占位图链接
现在谷歌图片采用懒加载策略,初始页面里的<img>标签的src属性并不是真实的图片链接,而是低分辨率的占位图(甚至多个img标签共用同一个占位图)。真实的图片链接通常存在data-src或者data-lazy-src这类属性里。你现在爬的都是同一个占位图,所以不管搜什么关键词,显示的都是同一张图。
2. tf.keras.utils.get_file的缓存坑
你给get_file传的文件名是固定的"images",这个函数默认会把下载的文件缓存到本地(路径一般是~/.keras/datasets/)。第一次下载狗的图片后,后续调用哪怕换了链接,只要文件名还是"images",它就会直接用缓存里的旧文件,不会重新下载,这也加重了重复的问题。
修正后的代码示例
我把你的脚本改了下,解决这两个问题:
import requests from bs4 import BeautifulSoup import tensorflow as tf import matplotlib.pyplot as plt # 加个User-Agent,避免被谷歌识别为机器人 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" } # 发送请求,带headers response = requests.get("https://www.google.com/search?q=cat&tbm=isch", headers=headers) doc = BeautifulSoup(response.text, "html.parser") all_imgs = [] # 遍历img标签,提取data-src属性(真实图片链接) for e in doc.select("img")[1:]: # 跳过第一个谷歌图标 # 优先取data-src,没有的话再尝试其他属性 img_url = e.get("data-src") or e.get("src") if not img_url: continue # 给每个图片生成唯一的文件名,避免缓存问题 img_filename = f"image_{hash(img_url)}.jpg" # 下载图片,设置cache_subdir避免和其他缓存混在一起,同时force_download=True强制重新下载 img_path = tf.keras.utils.get_file(img_filename, img_url, cache_subdir="google_images", force_download=True) img = tf.keras.utils.load_img(img_path, target_size=[90,90]) # 取链接的最后9位作为标题 all_imgs.append([img, img_url[-9:]]) # 展示图片 for idx, (img, title) in enumerate(all_imgs): plt.figure(idx) plt.imshow(img) plt.title(title) plt.show()
额外提醒
- 谷歌图片有反爬机制,频繁请求可能会被封IP,建议加个请求间隔(比如
time.sleep(1))。 - 如果还是拿不到真实链接,可能需要模拟滚动加载更多内容,但这会更复杂,适合用Selenium这类工具,但Colab里用Selenium需要额外配置浏览器驱动。
内容的提问来源于stack exchange,提问作者Sven
相关产品推荐
相关产品推荐

