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

Python for循环传值异常 Selenium爬虫触发NoSuchElementException报错

Selenium爬取时for循环中断、NoSuchElementException问题根因

核心问题本质

你遇到的循环中断、元素定位失败不是字符串格式化本身的bug,是代码逻辑存在多处明确错误,导致循环未按预期执行、翻页逻辑提前触发,最终元素查找失败。

代码中存在的明确Bug

  • 滚动逻辑未实际生效
    你写的滚动代码tartget_element.location_once_scrolled_into_view是WebElement的属性,不是可执行的方法,必须在末尾加括号写成tartget_element.location_once_scrolled_into_view()才会真正触发滚动。因为没有实际滚动,懒加载的列表不会渲染第11个及之后的元素,查找时直接抛出NoSuchElementException。
  • finally块逻辑错误,翻页被提前触发
    finally块的执行规则是:无论try块内代码是正常跑完还是抛出异常,finally块代码一定会强制执行。你把异常捕获的except块全注释了,try块里j=11查找元素抛异常时,不会做任何等待、重试,直接中断for循环跳去执行finally里的翻页代码——这就是为什么控制台只打印到0 page 11 element就直接输出click,根本没跑完单页50个元素的遍历。
  • 列表重复追加,存在大量冗余数据
    你在for循环内部写了keyword_address_list.extend(now_list),每遍历1个元素就把当前已收集的当前页数据全量追加一次,加上finally块里又做了一次追加,最终爬取到的数据会有大量重复值。
  • 字符串格式化占位符不匹配
    你用%语法做xpath字符串格式化时,如果xpath模板里没有写对应的%d(整数占位符),而是写了${j}这类不识别的占位符,格式化时不会替换序号位置,生成的xpath路径完全不符合预期,自然找不到对应元素。你观察到的"本该传入10实际传入1",本质是循环被异常打断后翻页提前执行,页面状态和循环变量j的序号不匹配,不是格式化逻辑自己传错了值。
  • 翻页等待逻辑不可靠
    翻页后只写了固定2秒的sleep,如果页面加载慢,还没等元素渲染完成就开始查找,也会触发找不到元素的错误。

修复参考代码

import time
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
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.Chrome(ChromeDriverManager().install())
wait = WebDriverWait(driver, 10)
# 省略打开目标页面、切入结果iframe的前置逻辑

page_num = 0
keyword_address_list = []
max_crawl_page = 20  # 设置最大爬取页数,避免死循环

while page_num < max_crawl_page:
    current_page_items = []
    # 遍历单页1-50个元素
    for j in range(1, 51):
        print(f"{page_num} page {j} element")
        # 注意xpath模板里用%d作为整数占位符,替换为j的值
        item_xpath = '//div[@class="result-item"][%d]' % j
        # 显式等待元素加载完成,替代固定等待
        target_element = wait.until(EC.presence_of_element_located((By.XPATH, item_xpath)))
        target_text = target_element.text
        current_page_items.append(target_text)

        # 每10个元素滚动一次,注意加括号调用滚动方法
        if j % 10 == 0:
            target_element.location_once_scrolled_into_view()
            time.sleep(0.5)
    # 单页所有元素爬取完成后,一次性追加到总列表,避免重复
    keyword_address_list.extend(current_page_items)

    # 单页爬完再执行翻页
    print("turn to next page")
    driver.switch_to.default_content()
    driver.switch_to.frame(result_frame)
    # 等待下一页按钮可点击后再点击
    next_btn = wait.until(EC.element_to_be_clickable((By.XPATH, '{next button xpath}')))
    next_btn.click()
    # 等待新页面第一个元素加载完成,确认翻页成功
    wait.until(EC.presence_of_element_located((By.XPATH, '//div[@class="result-item"][1]')))
    # 滚动回页面顶部
    driver.execute_script("window.scrollTo(0, 0)")
    page_num += 1

内容的提问来源于stack exchange,提问作者timothy jeong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 22:40:50