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

如何在Jsoup中设置延迟以等待JSON加载完成后抓取数据?

问题解决思路

Jsoup本身不支持等待异步JavaScript加载的功能——它只是发送HTTP请求获取页面的初始静态HTML,不会执行页面里的JS代码,自然也等不到异步加载的内容。针对你的问题,有两种更靠谱的解决方式:

1. 直接请求数据接口(推荐)

NBA Stats页面的球队数据都是通过后端API异步返回的,你可以直接抓这个接口的JSON数据,比模拟页面加载高效得多:

  • 打开浏览器开发者工具(F12),切换到「Network」标签,刷新页面
  • 过滤「XHR/Fetch」请求,找到返回球队四要素数据的接口(参数通常包含MeasureType=Four%20Factors)
  • 用Jsoup或者Java的Http客户端直接请求这个接口,拿到JSON后解析成Team对象即可。

2. 使用支持JS渲染的工具

如果一定要模拟浏览器加载页面,可以用Selenium或HtmlUnit这类工具,它们能执行页面JS并等待内容加载:

Selenium示例代码

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
import java.util.ArrayList;
import java.time.Duration;

public class Comparison {
    public void loadTeams() {
        // 配置ChromeDriver路径,需提前下载对应版本的驱动
        System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        
        try {
            driver.get("https://www.nba.com/stats/teams/four-factors");
            // 等待目标元素加载完成
            wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("[field='TEAM_NAME']")));
            
            ArrayList<Team> NBA = new ArrayList<>(30);
            // 提取数据
            java.util.List<WebElement> teamElements = driver.findElements(By.cssSelector("[field='TEAM_NAME']"));
            java.util.List<WebElement> shootingElements = driver.findElements(By.cssSelector("[field='EFG_PCT']"));
            java.util.List<WebElement> turnoversElements = driver.findElements(By.cssSelector("[field='TM_TOV_PCT']"));
            java.util.List<WebElement> reboundsElements = driver.findElements(By.cssSelector("[field='OREB_PCT']"));
            java.util.List<WebElement> freethrowsElements = driver.findElements(By.cssSelector("[field='FTA_PCTS']"));
            
            for (int i = 0; i < teamElements.size(); i++) {
                String name = teamElements.get(i).getText();
                double shootingScore = Double.parseDouble(shootingElements.get(i).getText());
                double turnoversScore = Double.parseDouble(turnoversElements.get(i).getText());
                double reboundsScore = Double.parseDouble(reboundsElements.get(i).getText());
                double freethrowsScore = Double.parseDouble(freethrowsElements.get(i).getText());
                NBA.add(new Team(name, shootingScore, turnoversScore, reboundsScore, freethrowsScore));
            }
            
            // 测试输出
            for(Team team : NBA) {
                System.out.println(team.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            driver.quit();
        }
    }
}

对你现有代码的说明

你当前用getElementsByAttributeValue查找的元素,是页面JS执行后动态生成的,初始HTML里根本不存在,所以Jsoup直接抓取会返回空集合——就算你在Jsoup.connect().get()前加Thread.sleep(),拿到的还是初始静态HTML,一样没有目标内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 11:43:11