百度图片无法用requests+BeautifulSoup直接抓取,因其依赖JS渲染且接口加密;应使用Selenium模拟浏览器并配置反检测参数,下载时需复用Referer和UA以避免403,同时对URL归一化和图片内容MD5去重。

requests + BeautifulSoup 抓取百度图片失败的常见原因
直接用 requests 请求百度图片搜索页,大概率拿到的是空结果或跳转到首页——因为百度图片现在完全依赖 JavaScript 渲染,requests 拿不到真实图片 URL。你看到的 HTML 里几乎没有 img 标签,只有占位容器和一堆 data-src 或 data-thumburl 属性,且这些字段被动态注入。
真正有效的做法是模拟 Ajax 请求,定位百度图片的接口地址(类似 /api/search/image 或带 tn=baiduimagedetail 的 referer),但该接口已加签名验证,参数(如 word、pn、rn)需配合时间戳、加密 token 才能生效,逆向成本高且极易失效。
- 别浪费时间写正则解析百度 HTML —— 它每天都在改 DOM 结构
- 不要尝试用
BeautifulSoup提取src属性 —— 大部分img标签的src是 placeholder(如data:image/png;base64,) - 如果必须用百度,建议改用其官方 API(需申请、有调用量限制),而非爬虫
用 Selenium + ChromeDriver 稳定获取图片 URL 的实操要点
Selenium 是目前最可靠的方式:它启动真实浏览器,等 JS 渲染完成后再提取 src 或 data-src。但默认配置下容易被识别为自动化工具,导致返回乱码、验证码或空列表。
关键在于启动参数和等待策略:
立即学习“Python免费学习笔记(深入)”;
- 必须禁用自动化特征:
options.add_argument('--disable-blink-features=AutomationControlled'),并手动删除navigator.webdriver属性 - 避免使用
time.sleep()等固定延时,改用WebDriverWait等待图片容器(如class="imgitem")出现 - 滚动到底部触发懒加载:执行
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);"),再等新元素出现 - 提取时优先读
data-src, fallback 到data-thumburl或src;过滤掉 base64 开头的无效值
示例片段(仅核心逻辑):
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
<p>options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-blink-features=AutomationControlled')
driver = webdriver.Chrome(options=options)
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
})
driver.get(f'<a href="https://www.php.cn/link/35bb97f361bcca162714c1c41fcfa775">https://www.php.cn/link/35bb97f361bcca162714c1c41fcfa775</a>}')
wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'imgitem')))</p><h1>后续滚动、提取、去重...下载图片时如何规避 403 和防盗链拦截
即使拿到 URL,直接用 requests.get(url) 下载常返回 403 Forbidden —— 因为目标服务器检查 Referer 和 User-Agent。百度、必应、谷歌图片都启用 Referer 防盗链。
解决办法不是伪造一个 UA 就完事,而是复用浏览器会话中的完整请求头:
- 从 Selenium 获取当前页面的
driver.get_cookies()并转为requests可用格式(注意 domain 匹配) - 必须带上原始 Referer:
headers['Referer'] = driver.current_url - UA 要和 driver 启动时一致,可通过
driver.execute_script("return navigator.userAgent")动态获取 - 对每个图片 URL 单独构造 session,避免 cookie 过期或污染
漏掉 Referer 或用错 UA,90% 的图片链接会直接 403。这不是网络问题,是服务端明确拒绝。
关键词搜索结果去重与文件名安全处理
同一张图在不同分页或不同尺寸下可能重复出现,URL 中常含随机参数(如 &t=xxx、&s=yyy),直接按 URL 哈希会误判为不同图片。
更稳妥的做法是截取 URL 中的主路径部分(去掉查询参数),再对响应内容做 MD5 校验:
- 用
urllib.parse.urlparse(url).scheme + '://' + urllib.parse.urlparse(url).netloc + urllib.parse.urlparse(url).path归一化 URL - 下载后读取二进制内容,计算
hashlib.md5(content).hexdigest(),用该 hash 做文件名前缀 - 文件扩展名不能全信响应头里的
Content-Type,要结合 magic bytes 判断(如用python-magic库) - Windows 下避免文件名含
< > : " / | ? *,用re.sub(r'[\/*?<>|]', '_', filename)清洗
没做归一化和内容校验,你下载 100 张图,实际可能只有 30 张是真不同的——其余全是缩略图、水印图或参数变体。

















