网页循环爬取问题:仅获最后一条链接数据的排查与优化
问题分析与解决方案
我需要爬取基于JavaScript渲染的网站https://www.itf.gov.hk/en/project-search/search-result/index.html?isAdvSearch=1&Programmes=TVP,将每个链接的信息汇总到Excel文件中。但读取存储链接的Excel文件进行循环处理时,代码仅能获取最后一条链接的数据,求问题原因及其他实现方法。
原代码
from tkinter import X import openpyxl from selenium import webdriver from selenium.webdriver.common.by import By import time from selenium.common.exceptions import NoSuchElementException from webdriver_manager.chrome import ChromeDriverManager import pandas as pd links = [] wb = openpyxl.load_workbook('a.xlsx') sheet = wb.active #for reading the excel files for x in range(1,12319,1): links.append(sheet.cell(x,2).value) print("size of links = ", len(links)) headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml; q=0.9,image/webp,image/apng,*/*;q=0.8" } for i in range(0,12319): url = links[i] options = webdriver.ChromeOptions() driver = webdriver.Chrome(options=options, executable_path=ChromeDriverManager().install()) driver.get(url) time.sleep (2) # getting the name of the line and its content data = {} index_elem = 1 while True: # through the lines until we reach the non-existent try: columns_name = driver.find_element( By.XPATH, f'//*[@id="projectProfile"]/table/tbody/tr[{index_elem}]/th').text columns_content = driver.find_element( By.XPATH, f'//*[@id="projectProfile"]/table/tbody/tr[{index_elem}]/td').text data[columns_name] = [columns_content] index_elem += 1 except NoSuchElementException: break df = pd.DataFrame(data) df.to_excel('tvp.xlsx')
问题原因
- 循环逻辑错误:
for循环内每次创建新Chrome驱动并打开链接,但循环结束后才执行数据提取代码,仅最后一次打开的页面会被处理,前面所有页面的操作都未保存数据。 - 数据存储逻辑错误:
data字典在循环外初始化,仅能存储最后一个页面的数据;且每个字段用列表存储的方式无法累积多条记录。 - 资源浪费:循环内重复创建驱动却不关闭,会打开上千个Chrome窗口,严重消耗系统资源。
修正后的代码
import openpyxl from selenium import webdriver from selenium.webdriver.common.by import By from selenium.common.exceptions import NoSuchElementException from webdriver_manager.chrome import ChromeDriverManager import pandas as pd # 读取链接列表,过滤空链接 links = [] wb = openpyxl.load_workbook('a.xlsx') sheet = wb.active for x in range(1, 12319): link = sheet.cell(x, 2).value if link: links.append(link) print(f"有效链接数量: {len(links)}") # 初始化Chrome驱动(仅初始化一次) options = webdriver.ChromeOptions() options.add_argument('--headless=new') # 无头模式,不显示浏览器窗口 options.add_argument('--disable-gpu') driver = webdriver.Chrome(options=options, executable_path=ChromeDriverManager().install()) driver.implicitly_wait(5) # 隐式等待,替代time.sleep,提升效率与稳定性 all_data = [] # 存储所有页面的数据 for url in links: try: driver.get(url) page_data = {} index_elem = 1 while True: try: col_name = driver.find_element(By.XPATH, f'//*[@id="projectProfile"]/table/tbody/tr[{index_elem}]/th').text col_content = driver.find_element(By.XPATH, f'//*[@id="projectProfile"]/table/tbody/tr[{index_elem}]/td').text page_data[col_name] = col_content index_elem += 1 except NoSuchElementException: break all_data.append(page_data) print(f"已处理链接: {url}") except Exception as e: print(f"处理链接{url}时出错: {str(e)}") continue # 关闭驱动,释放资源 driver.quit() # 生成DataFrame并保存到Excel df = pd.DataFrame(all_data) df.to_excel('tvp_all_data.xlsx', index=False)
优化建议
- 使用隐式/显式等待:替代固定时长的
time.sleep,等待元素加载完成后再执行操作,提升爬取稳定性与效率。 - 无头模式运行:减少系统资源占用,适合大规模批量爬取场景。
- 异常捕获机制:针对单个链接的错误进行捕获处理,避免程序因个别异常直接崩溃。
- 分批次保存数据:若链接数量极大,可每处理一定数量的链接就保存一次数据,防止意外情况导致数据丢失。
- 封装元素定位:若页面结构复杂,可使用Selenium的Page Object模式封装元素定位逻辑,提升代码可维护性。
内容的提问来源于stack exchange,提问作者Madd Kit
相关产品推荐
相关产品推荐

