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

网页循环爬取问题:仅获最后一条链接数据的排查与优化

问题分析与解决方案

我需要爬取基于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')

问题原因

  1. 循环逻辑错误:for循环内每次创建新Chrome驱动并打开链接,但循环结束后才执行数据提取代码,仅最后一次打开的页面会被处理,前面所有页面的操作都未保存数据。
  2. 数据存储逻辑错误:data字典在循环外初始化,仅能存储最后一个页面的数据;且每个字段用列表存储的方式无法累积多条记录。
  3. 资源浪费:循环内重复创建驱动却不关闭,会打开上千个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)

优化建议

  1. 使用隐式/显式等待:替代固定时长的time.sleep,等待元素加载完成后再执行操作,提升爬取稳定性与效率。
  2. 无头模式运行:减少系统资源占用,适合大规模批量爬取场景。
  3. 异常捕获机制:针对单个链接的错误进行捕获处理,避免程序因个别异常直接崩溃。
  4. 分批次保存数据:若链接数量极大,可每处理一定数量的链接就保存一次数据,防止意外情况导致数据丢失。
  5. 封装元素定位:若页面结构复杂,可使用Selenium的Page Object模式封装元素定位逻辑,提升代码可维护性。

内容的提问来源于stack exchange,提问作者Madd Kit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 01:15:39