Python+Selenium网站爬取问题:点击图片下载按钮失败
问题描述
我是Python和网页爬取新手,需要从https://historisch.cbs.nl/detail.php?nav_id=0-1&index=2&id=30568043这类链接下载系列图片(仅URL末尾数字部分变化),目标是点击页面上的两个下载按钮将图片保存到本地。
我的代码如下:
browser = webdriver.Chrome(service=s, options=chrome_options) for i in range(8047,8051): no = str(i) browser.get ("https://historisch.cbs.nl/detail.php?nav_id=1-1&index=2&id=3056"+str(i)+".jpeg") download = WebDriverWait(browser, 5).until(EC.element_to_be_clickable((By.XPATH,'//*[@id="downloadDirect"]'))) download.click() t.sleep(1) download = WebDriverWait(browser, 3).until(EC.element_to_be_clickable((By.XPATH,'//*[@id="downloadResLink"]'))) download.click()
运行时出现TimeoutException错误:
----> 8 download = WebDriverWait(browser, 5).until(EC.element_to_be_clickable((By.XPATH,'//*[@id="downloadDirect"]'))) 9 download.click() 10 t.sleep(1) ~\anaconda3\lib\site-packages\selenium\webdriver\support\wait.py in until(self, method, message) 88 if time.monotonic() > end_time: 89 break ---> 90 raise TimeoutException(message, screen, stacktrace) 91 92 def until_not(self, method, message: str = ""): TimeoutException: Message: Stacktrace: Backtrace: Ordinal0 [0x00371ED3+2236115] Ordinal0 [0x003092F1+1807089] Ordinal0 [0x002166FD+812797] Ordinal0 [0x002455DF+1005023] Ordinal0 [0x002457CB+1005515] Ordinal0 [0x00277632+1209906] Ordinal0 [0x00261AD4+1120980] Ordinal0 [0x002759E2+1202658] Ordinal0 [0x002618A6+1120422] Ordinal0 [0x0023A73D+960317] Ordinal0 [0x0023B71F+964383] GetHandleVerifier [0x0061E7E2+2743074] GetHandleVerifier [0x006108D4+2685972] GetHandleVerifier [0x00402BAA+532202] GetHandleVerifier [0x00401990+527568] Ordinal0 [0x0031080C+1837068] Ordinal0 [0x00314CD8+1854680] Ordinal0 [0x00314DC5+1854917] Ordinal0 [0x0031ED64+1895780] BaseThreadInitThunk [0x75B4FA29+25] RtlGetAppContainerNamedObjectPath [0x779A7BBE+286] RtlGetAppContainerNamedObjectPath [0x779A7B8E+238]
解决方案
1. 修复代码缩进问题
下载代码块不在for循环内部,只会在循环结束后执行一次,导致前面的页面加载后未处理,且最后一个页面可能加载异常。调整缩进:
import time 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 browser = webdriver.Chrome(service=s, options=chrome_options) for i in range(8047,8051): no = str(i) browser.get(f"https://historisch.cbs.nl/detail.php?nav_id=1-1&index=2&id=3056{i}.jpeg") # 等待第一个下载按钮可点击并点击 download = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.ID, 'downloadDirect'))) download.click() time.sleep(1) # 确保下载请求发出 # 等待第二个下载按钮可点击并点击 download = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.ID, 'downloadResLink'))) download.click() time.sleep(1) # 给页面足够时间处理跳转
2. 优化等待策略
- 延长等待时间:从5秒增加到10秒,避免网络延迟导致元素未加载完成。
- 改用
By.ID定位:比XPATH更高效稳定,因为ID是页面唯一标识。
3. 检查URL正确性
对比示例链接https://historisch.cbs.nl/detail.php?nav_id=0-1&index=2&id=30568043,代码中的URL使用nav_id=1-1,确认是否为目标页面的正确参数,参数错误会导致页面加载异常,找不到下载按钮。
4. 处理可能的弹窗或iframe
如果页面存在弹窗或iframe,需先切换上下文才能定位元素:
- 处理弹窗:
# 检查并关闭alert弹窗 try: alert = WebDriverWait(browser, 3).until(EC.alert_is_present()) alert.accept() except TimeoutException: pass
- 切换iframe(若下载按钮在iframe内):
# 替换为实际iframe的定位方式,比如ID、name等 iframe = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, '目标iframe的ID'))) browser.switch_to.frame(iframe) # 定位并点击下载按钮... # 操作完成后切回主文档 browser.switch_to.default_content()
5. 指定下载路径(可选)
若需要自定义下载目录,可在ChromeOptions中配置:
chrome_options = webdriver.ChromeOptions() prefs = {'download.default_directory': '你的本地保存路径(如C:\\downloads)'} chrome_options.add_experimental_option('prefs', prefs)
内容的提问来源于stack exchange,提问作者Lucia Vai
相关产品推荐
相关产品推荐

