Python网页爬虫:迭代时如何跳过不存在的元素?
优化方案:避免异常触发提升爬虫效率
你的核心问题是通过try-except捕获元素不存在的异常,频繁触发异常导致爬取速度变慢。可以通过直接在列表项内部定位元素+使用复数查找方法判断元素存在性来解决,完全避免异常触发,同时提升稳定性和速度。
关键优化点
- 放弃通过索引拼接全局XPATH的方式,直接遍历已获取的
savings列表项,在每个项的上下文内查找子元素 - 用
find_elements()(复数形式)替代显式等待单个元素,找不到时返回空列表,无异常抛出 - 替换冗余的
time.sleep为显式等待,减少不必要的等待时间 - 优化
read more按钮的点击逻辑,避免重复定位所有按钮
修改后的完整代码
import datetime import pandas as pd 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.Chrome() url = 'https://www.ratecity.com.au/savings-accounts' driver.get(url) # 用显式等待替代固定sleep,等待页面滚动后元素加载 WebDriverWait(driver, 30).until(lambda d: d.execute_script("return document.documentElement.scrollHeight > 1080")) driver.execute_script("window.scrollTo(0, 1080)") WebDriverWait(driver, 30).until(lambda d: d.execute_script("return document.documentElement.scrollHeight > 2080")) driver.execute_script("window.scrollTo(0, 2080)") get_today = datetime.datetime.now() today = get_today.strftime('%d/%m/%Y') affiliate = 'RateCity' rank = 1 results = [['Date', 'Affiliate', 'Position', 'Provider', 'Product', 'Maximum Rate', 'Standard Rate', 'Max Rate Conditions', 'Savings Details']] load_more_button = '//*[@id="__next"]/div/main/div[3]/div/div[2]/div[4]/div[1]/div/button' load_more_clicks = 2 for _ in range(1, load_more_clicks): btn = WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.XPATH, load_more_button))) driver.execute_script('arguments[0].click();', btn) # 等待加载更多后内容更新 WebDriverWait(driver, 30).until(EC.staleness_of(btn)) # 优化read more点击:遍历每个按钮并点击 read_more_buttons = WebDriverWait(driver, 30).until(EC.presence_of_all_elements_located((By.XPATH, '//*[@id="rc-ratetable"]/div/div//span[contains(text()," ...read more")]'))) for btn in read_more_buttons: if btn.is_displayed(): driver.execute_script('arguments[0].click();', btn) # 等待展开完成 WebDriverWait(driver, 10).until(EC.text_to_be_present_in_element((By.XPATH, './..'), ' ...read less')) # 获取所有列表项 savings = WebDriverWait(driver, 30).until(EC.presence_of_all_elements_located((By.XPATH, '//*[@id="rc-ratetable"]/div/div'))) # 遍历每个列表项,在项内查找元素 for item in savings: # 在当前item下查找目标元素,用find_elements避免异常 condition_elements = item.find_elements(By.XPATH, './div[2]/div[2]/div[4]/p') if condition_elements: savings_conditions = condition_elements[0].text.replace(' ...read less', '') else: savings_conditions = 'No max rate conditions listed' print(savings_conditions) driver.quit()
优化说明
- 元素定位逻辑:
不再拼接div[{i}]这种全局索引XPATH,而是直接在每个savings项内部用相对路径./div[2]/div[2]/div[4]/p查找,定位更精准,避免页面结构变化导致的索引失效。 - 避免异常触发:
使用find_elements()方法,找不到元素时返回空列表,直接判断列表是否非空即可,完全避免NoSuchElementException的抛出,大幅提升速度。 - 等待逻辑优化:
用WebDriverWait替代固定time.sleep,比如等待滚动后页面高度变化、等待加载更多按钮失效(staleness_of)、等待read more按钮切换为read less,让等待更智能,减少不必要的耗时。 - read more点击优化:
直接遍历已获取的按钮列表,避免每次循环重新定位所有按钮,同时判断按钮是否可见,避免重复点击已展开的按钮。
内容的提问来源于stack exchange,提问作者notoriousBBG
相关产品推荐
相关产品推荐

