能否通过Python的Selenium下载服务器动态生成的网站图片?
如何用Selenium下载服务器动态生成的图片?
我在Web Inspector中发现某网站(示例域名)有一张服务器动态生成的图片,链接为https://somesite.com/asd/photo.pl?num=10,尝试用Selenium结合requests下载但失败,推测是服务器端验证导致的。
原尝试代码:
from selenium import webdriver import urllib.request import shutil import time import requests driver = webdriver.Firefox() driver.get("https://somesite.com/") img = driver.find_element(By.XPATH, '/html/body/div[2]/div/div[1]/a/img') img_url = img.get_attribute('src') response = requests.get(img_url) with open("saved_image.jpg", "wb") as file: file.write(response.content)
问题原因
直接用requests.get(img_url)发起的请求没有继承Selenium浏览器的会话状态(比如Cookie、User-Agent等),动态生成图片的服务器通常会验证请求是否来自合法的浏览器会话,无会话信息的请求会被拦截。
解决方案
方案1:直接对图片元素截图
利用Selenium的元素截图功能,直接捕获浏览器渲染后的图片,无需单独请求图片链接,能绕过会话验证:
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 driver = webdriver.Firefox() driver.get("https://somesite.com/") # 显式等待图片加载完成,比time.sleep更可靠 img = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, '/html/body/div[2]/div/div[1]/a/img')) ) # 对图片元素进行截图保存 img.screenshot("saved_image.jpg") driver.quit()
注意:截图的质量取决于浏览器渲染的尺寸,如果需要原图分辨率,优先考虑方案2。
方案2:继承浏览器会话状态请求图片
提取Selenium中的Cookie和浏览器标识,用requests模拟浏览器请求,获取原图:
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 import requests driver = webdriver.Firefox() driver.get("https://somesite.com/") img = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, '/html/body/div[2]/div/div[1]/a/img')) ) img_url = img.get_attribute('src') # 提取浏览器的Cookie和User-Agent cookies = driver.get_cookies() headers = { 'User-Agent': driver.execute_script("return navigator.userAgent;"), 'Referer': driver.current_url # 部分服务器会验证Referer来源 } # 初始化requests会话,注入浏览器Cookie session = requests.Session() for cookie in cookies: session.cookies.set(cookie['name'], cookie['value']) # 发起请求获取图片 response = session.get(img_url, headers=headers) # 验证请求是否成功 if response.status_code == 200: with open("saved_image.jpg", "wb") as file: file.write(response.content) else: print(f"请求失败,状态码:{response.status_code}") driver.quit()
额外提示
- 尽量使用显式等待替代固定延迟,确保图片元素已加载完成再操作。
- 若服务器反爬机制严格,可添加更多浏览器请求头(如
Accept、Accept-Language),或模拟滚动到图片位置等用户行为。
内容的提问来源于stack exchange,提问作者Mirek
相关产品推荐
相关产品推荐

