You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 10:50:36