使用Selenium爬取滚动加载网页失败,遇JQuery未定义错误求助
解决Selenium滚动加载tender247.com时的"JQuery not defined"和属性未定义错误
问题根源分析
- "JQuery not defined":该网站未全局引入JQuery,或你的代码过早执行了依赖JQuery的操作,此时JQuery还未加载完成。
- "Cannot read properties of undefined":滚动后目标数据元素未完全加载,导致代码尝试访问未初始化的对象/属性。
解决方案
1. 等待JQuery加载(若网站确实使用JQuery)
如果滚动逻辑依赖JQuery,先确保JQuery已加载完成再执行操作:
from selenium.webdriver.support.ui import WebDriverWait # 等待JQuery全局对象存在 WebDriverWait(driver, 10).until( lambda d: d.execute_script("return typeof jQuery !== 'undefined';") )
2. 改用原生JavaScript滚动(推荐,避免JQuery依赖)
直接用原生JS实现滚动,稳定性更高:
# 滚动到页面底部触发加载 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 或滚动到最后一条招标条目,精准触发加载 last_item = driver.find_elements_by_css_selector(".tender-item")[-1] driver.execute_script("arguments[0].scrollIntoView({behavior: 'smooth'});", last_item)
3. 滚动后验证内容加载状态
每次滚动后,等待新内容加载完成,避免访问未定义元素:
import time from selenium.webdriver.support.ui import WebDriverWait previous_count = 0 max_empty_scrolls = 3 # 连续3次无新内容则停止 while max_empty_scrolls > 0: current_items = driver.find_elements_by_css_selector(".tender-item") current_count = len(current_items) if current_count == previous_count: max_empty_scrolls -= 1 else: max_empty_scrolls = 3 # 有新内容则重置计数 previous_count = current_count # 滚动加载 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 等待内容加载(可根据页面响应速度调整时间) time.sleep(2) # 可选:用显式等待确认新元素出现 WebDriverWait(driver, 5).until( lambda d: len(d.find_elements_by_css_selector(".tender-item")) >= previous_count )
4. 安全提取数据,避免属性未定义
提取数据前先检查元素是否存在,防止访问未定义属性:
for item in current_items: # 提取标题 title_elem = item.find_elements_by_css_selector(".tender-title") title = title_elem[0].text if title_elem else "无标题" # 提取日期 date_elem = item.find_elements_by_css_selector(".tender-date") tender_date = date_elem[0].text if date_elem else "无日期" print(f"标题:{title},日期:{tender_date}")
完整可运行示例代码
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait import time driver = webdriver.Chrome() driver.get("https://www.tender247.com/keyword/mall+Tenders") driver.maximize_window() # 等待初始页面加载完成 WebDriverWait(driver, 10).until( lambda d: len(d.find_elements_by_css_selector(".tender-item")) > 0 ) previous_count = 0 max_empty_scrolls = 3 while max_empty_scrolls > 0: current_items = driver.find_elements_by_css_selector(".tender-item") current_count = len(current_items) if current_count == previous_count: max_empty_scrolls -= 1 else: max_empty_scrolls = 3 previous_count = current_count # 滚动到最后一条条目 if current_items: driver.execute_script("arguments[0].scrollIntoView({block: 'end'});", current_items[-1]) time.sleep(3) # 批量提取数据 tender_list = [] for item in current_items: title = item.find_element_by_css_selector(".tender-title").text if item.find_elements_by_css_selector(".tender-title") else "N/A" org = item.find_element_by_css_selector(".tender-org").text if item.find_elements_by_css_selector(".tender-org") else "N/A" tender_list.append({"标题": title, "发布机构": org}) print(f"共抓取到 {len(tender_list)} 条招标信息") driver.quit()
内容的提问来源于stack exchange,提问作者Heller_ 313
相关产品推荐
相关产品推荐

