使用Python Selenium爬取动态网站遇滚动加载问题求助
解决USASpending.gov滚动加载数据爬取问题
我尝试爬取以下URL的动态数据:
url=https://www.usaspending.gov/search/?hash=7e5e5a79e871a86ff6b69395e47ab41e
但页面存在滚动加载,导致无法爬取全部数据。我尝试的代码如下:
import requests import time from selenium import webdriver from bs4 import BeautifulSoup from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.action_chains import ActionChains driver=webdriver.Chrome() url = "https://www.usaspending.gov/search/?hash=7e5e5a79e871a86ff6b69395e47ab41e" driver.get(url) action = ActionChains(driver) from selenium.webdriver.common.by import By time.sleep(7) headings_row = driver.find_elements(By.CLASS_NAME, 'award-result-header-cell') award_link = driver.find_elements(By.PARTIAL_LINK_TEXT, 'FA') link="/recipient/" recp_link = driver.find_elements(By.XPATH,'//a[@href="'+link+'"]') list_headings_row = [] award_id = [] reciepient = [] for i in range(15): list_headings_row.append(headings_row[i].text) award_id.append(award_link[i].text) reciepient.append(recp_link[i].text) print(list_headings_row)
打印list_headings_row得到的结果如下:
['Award ID', 'Recipient Name', 'Start Date\n(Period of Performance)', 'End Date\n(Period of Performance)', '', '', '',
'', '', '', '', '', '', '', '']
问题分析
- 未处理滚动加载:页面数据随滚动逐步加载,现有代码未触发滚动操作,只能获取初始加载的少量数据。
- 元素定位错误:收件人链接的XPATH写死为
/recipient/,但实际链接是带具体ID的(如/recipient/12345/),导致无法匹配有效元素,返回空文本。 - 硬编码等待不可靠:
time.sleep(7)固定等待时间,无法适配不同网络环境下的页面加载速度,可能导致元素未加载完成。 - 硬编码循环次数:
range(15)强制循环15次,实际表头数量不足时会引发索引越界,且未处理动态加载的数据行。
优化后的解决方案代码
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 # 初始化Chrome浏览器 driver = webdriver.Chrome() url = "https://www.usaspending.gov/search/?hash=7e5e5a79e871a86ff6b69395e47ab41e" driver.get(url) # 设置显式等待最长时间20秒 wait = WebDriverWait(driver, 20) # 等待表头元素加载完成 wait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'award-result-header-cell'))) # 处理滚动加载:循环滚动到底部直到没有新数据加载 last_scroll_height = driver.execute_script("return document.body.scrollHeight") while True: # 执行JavaScript滚动到页面底部 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 等待新数据加载(可根据网络情况调整时间) time.sleep(3) # 获取新的滚动高度 new_scroll_height = driver.execute_script("return document.body.scrollHeight") # 如果滚动高度不再变化,说明没有新数据了 if new_scroll_height == last_scroll_height: break last_scroll_height = new_scroll_height # 提取并清洗表头数据(过滤空文本) headings = driver.find_elements(By.CLASS_NAME, 'award-result-header-cell') clean_headings = [heading.text.strip() for heading in headings if heading.text.strip()] print("清洗后的表头:", clean_headings) # 提取所有Award ID(匹配以FA开头的链接) award_links = driver.find_elements(By.PARTIAL_LINK_TEXT, 'FA') award_ids = [link.text.strip() for link in award_links] print("Award ID示例(前5个):", award_ids[:5]) # 提取所有收件人名称(匹配包含/recipient/的链接) recipient_links = driver.find_elements(By.XPATH, '//a[contains(@href, "/recipient/")]') recipients = [link.text.strip() for link in recipient_links] print("收件人名称示例(前5个):", recipients[:5]) # 关闭浏览器 driver.quit()
关键优化说明
- 滚动加载处理:通过JavaScript滚动+高度检测,确保所有动态加载的数据都被加载出来。
- 显式等待:用
WebDriverWait等待元素加载完成,替代固定等待时间,提升代码稳定性。 - 元素定位修正:收件人链接用
contains(@href, "/recipient/")匹配所有相关链接,避免写死具体路径。 - 数据清洗:过滤空文本,只保留有效表头和数据,避免输出大量空值。
- 避免索引越界:遍历所有找到的元素,而非硬编码循环次数,适配不同数据量。
内容的提问来源于stack exchange,提问作者amnpawar
相关产品推荐
相关产品推荐

