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

Java+Selenium爬取网页表格速度缓慢,求原因及优化方案

爬取速度缓慢的原因分析与优化方案

核心问题原因

  • Excel写入的重复IO操作:当前XLUtils.setCellData方法每写入一个单元格,都会重复执行「打开文件流→创建Workbook→写入单元格→关闭流/Workbook」的流程,随着行数增多,磁盘IO开销会指数级上升,这是速度越来越慢的核心原因。
  • Selenium元素重复定位:内层循环中每次通过rows.get(r).findElement(By.xpath(".//td["+(c+1)+"]"))查找单元格,相当于每次都重新遍历DOM树,重复的元素定位会累积大量耗时。
  • 冗余的文本获取:空行判断时重复调用getText(),该方法会触发Selenium与浏览器的通信,两次调用完全没必要。
  • 全局隐式等待的累加影响:设置了10秒全局隐式等待,单次操作影响不明显,但大量元素查找会把等待时间的开销累积起来。

针对性优化方案

1. 重构Excel工具类,实现批量写入

将Workbook、文件流的打开/关闭操作放到整个写入流程的首尾,仅执行一次,所有单元格写入完成后再统一保存到文件,彻底消除重复IO的开销。

修改后的XLUtils示例:

package com.internetBanking.utilities;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;

public class XLUtils {
    private HSSFWorkbook wb;
    private HSSFSheet ws;
    private String xlFile;

    // 构造方法初始化Workbook和Sheet
    public XLUtils(String xlFile, String xlsheet) throws IOException {
        this.xlFile = xlFile;
        FileInputStream fi = new FileInputStream(xlFile);
        wb = new HSSFWorkbook(fi);
        ws = wb.getSheet(xlsheet);
        fi.close();
    }

    // 写入单个单元格(仅内存操作,无磁盘IO)
    public void setCellData(int rowNum, int colNum, String data) {
        HSSFRow row = ws.getRow(rowNum);
        if (row == null) {
            row = ws.createRow(rowNum);
        }
        Cell cell = row.createCell(colNum);
        cell.setCellValue(data);
    }

    // 统一保存所有修改到文件
    public void save() throws IOException {
        FileOutputStream fo = new FileOutputStream(xlFile);
        wb.write(fo);
        fo.close();
        wb.close();
    }

    // 保留原有工具方法(按需使用)
    public static int getRowCount(String xlfile, String xlsheet) throws IOException {
        FileInputStream fi = new FileInputStream(xlfile);
        HSSFWorkbook wb = new HSSFWorkbook(fi);
        HSSFSheet ws = wb.getSheet(xlsheet);
        int rowcount = ws.getLastRowNum();
        wb.close();
        fi.close();
        return rowcount;
    }
}

主类中对应的Excel写入逻辑修改:

// 初始化Excel工具类(仅执行一次)
xl = new XLUtils(".\\datafiles\\covid.xls", "Covid Data");

// 写入表头
for(int col=1; col<header.size()-1; col++) {
    xl.setCellData(0, col-1, header.get(col).getText());
}

int xlRow = 1;
                
for(int r=1; r<rows.size(); r++) {
    String rowText = rows.get(r).getText();
    if(rowText.equals("")) {
        System.out.println("Skipped row: "+r);
        continue;
    }
    System.out.println("Writing row "+r);   
    
    // 一次性获取当前行所有单元格,避免重复DOM查找
    List<WebElement> cells = rows.get(r).findElements(By.xpath(".//td"));
    for(int c=1; c<header.size(); c++) {
        // 处理单元格索引边界,避免数组越界
        String cellData = cells.size() > c ? cells.get(c).getText() : "";
        xl.setCellData(xlRow, c-1, cellData);
    }
    xlRow++;
}

// 所有数据写入完成后,统一保存到文件
xl.save();

2. Selenium端性能优化

  • 缓存行内单元格元素:遍历行时一次性获取所有td元素并缓存,避免内层循环重复调用findElement。
  • 减少重复的getText()调用:行文本仅获取一次,同时用于空行判断和后续逻辑。
  • 改用显式等待替代全局隐式等待:只在表格加载等关键节点使用显式等待,避免全局等待的不必要延迟:
    // 替换原有的implicitlyWait
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("main_table_countries_today")));
    
  • 启用无头模式:无需可视化界面时,开启Chrome无头模式减少渲染开销:
    WebDriverManager.chromedriver().setup();
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--headless=new");
    options.addArguments("--disable-gpu");
    driver = new ChromeDriver(options);
    
  • 替换XPath为CSS选择器:CSS选择器的定位速度通常优于XPath,比如将行定位改为:
    rows = table.findElements(By.cssSelector("tr[role='row']"));
    

3. 细节优化

  • 降低控制台输出频率:如果每行都打印Writing row xxx,IO输出会占用额外资源,可以改为每10行打印一次,或仅打印关键节点信息。
  • 提前过滤空行:在获取行列表后,先过滤掉空行,减少后续循环次数:
    rows = rows.stream().filter(row -> !row.getText().isEmpty()).collect(Collectors.toList());
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 12:25:15