
本文详解使用 python requests 库加载动态生成的 php 验证码图片的关键要点:必须先访问表单页面获取会话 cookie,再携带该 cookie 请求验证码 url,否则将因会话缺失而返回空白或错误响应。
本文详解使用 python requests 库加载动态生成的 php 验证码图片的关键要点:必须先访问表单页面获取会话 cookie,再携带该 cookie 请求验证码 url,否则将因会话缺失而返回空白或错误响应。
在自动化采集验证码图像(如用于后续 OCR 或深度学习识别)时,一个常见误区是直接请求验证码 URL(如 simple-php-captcha.php),却忽略其背后的会话依赖机制。目标站点(如 https://dpdc.org.bd)使用的 PHP 验证码脚本(simple-php-captcha.php)并非无状态资源——它依赖服务端 PHP Session 来生成和关联验证码文本与图像。若未建立有效会话,服务器将拒绝提供有效图片(可能返回 0 字节、占位图、HTTP 500 或重定向)。
✅ 正确做法是执行两步请求流程:
- 首次 GET 表单页面(如 https://dpdc.org.bd/site/service/ebill_gov/):触发服务器创建 Session,并通过 Set-Cookie 响应头下发 PHPSESSID 等会话 Cookie;
- 二次 GET 验证码 URL:复用上一步获取的 requests.cookies.RequestsCookieJar,确保请求携带有效会话标识。
以下是完整、健壮的实现示例(含异常处理与自动 URL 提取建议):
import requests
from urllib.parse import urljoin, urlparse
# Step 1: 获取表单页并提取会话 Cookie
session = requests.Session()
form_url = "https://dpdc.org.bd/site/service/ebill_gov/"
try:
form_resp = session.get(form_url, timeout=10)
form_resp.raise_for_status()
except requests.exceptions.RequestException as e:
raise RuntimeError(f"无法访问表单页: {e}")
# ✅ 关键:Session 自动管理 cookies,无需手动传入
# (也可显式使用 session.cookies,效果等同)
# Step 2: 构造或提取验证码 URL(推荐动态解析,避免硬编码时间戳)
# 示例:若验证码 URL 内嵌于 HTML 中(如 <img src="...">),可使用 BeautifulSoup 解析:
# from bs4 import BeautifulSoup
# soup = BeautifulSoup(form_resp.text, 'html.parser')
# captcha_img = soup.find('img', {'id': 'captcha-image'}) or soup.find('img', alt='Captcha')
# captcha_url = urljoin(form_url, captcha_img['src']) if captcha_img else None
# 若 URL 已知(如问题中给出),需注意:t 参数为时间戳+随机数,通常可省略或保留原值;
# 但更稳妥方式是每次从页面实时提取,避免过期失效。
captcha_url = "https://dpdc.org.bd/site/application/libs/captcha/simple-php-captcha.php?_CAPTCHA&t=0.22003900+1651258878"
try:
captcha_resp = session.get(captcha_url, timeout=10)
captcha_resp.raise_for_status()
# 验证响应内容是否为有效 PNG 图像(可选校验)
if captcha_resp.headers.get('content-type', '').lower().startswith('image/'):
with open("captcha.png", "wb") as f:
f.write(captcha_resp.content)
print("✅ 验证码图片已成功保存为 captcha.png")
else:
print("⚠️ 警告:响应不是图像类型,Content-Type =", captcha_resp.headers.get('content-type'))
print("响应内容前100字节:", captcha_resp.content[:100])
except requests.exceptions.RequestException as e:
raise RuntimeError(f"获取验证码图片失败: {e}")? 重要注意事项:
- ❌ 不要跳过第一步直接请求验证码 URL —— 这是绝大多数“图片为空”问题的根源;
- ⚠️ 避免硬编码带时间戳的 t= 参数(如 t=0.84582400+1651208314),因其可能被服务端校验时效性;优先从 HTML 源码中动态提取 <img> 的 src 属性;
- ? 使用 requests.Session() 是最佳实践,它自动维护 Cookie、连接池与请求上下文,比手动传递 cookies= 更可靠;
- ? 若仍失败,可用 print(form_resp.cookies) 和 print(captcha_resp.status_code, captcha_resp.headers) 调试会话是否传递成功及响应状态;
- ? 注意目标网站的 robots.txt 及使用条款,验证码采集应仅用于合法、合规的学习或授权用途。
完成此步骤后,你即可获得真实、可识别的 PNG 验证码图像,无缝接入 Keras/TensorFlow 等模型进行训练与推理。

















