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

使用InputStream.openStream()获取YouTube页面返回非HTML代码的问题

解决YouTube页面爬取播放量的问题

问题根源

直接用URL.openStream()请求YouTube页面,会因为以下两个原因导致拿到的内容和浏览器检查元素不一致:

  1. YouTube会识别非浏览器请求,返回简化版静态HTML,播放量这类核心数据不会直接出现在初始响应里;
  2. 你的代码存在**重复调用readLine()**的错误,导致一半页面内容被跳过,无法完整获取响应。

解决步骤

1. 修复内容读取错误

你的循环里,while(in.readLine() != null)已经读取了一行,之后又调用String s = (in.readLine()),这会跳过下一行数据。正确的读取方式应该是把读取的行存下来判断:

String line;
while ((line = in.readLine()) != null) {
    code.add(line);
    c++;
}

2. 模拟浏览器请求头

YouTube会验证请求的User-Agent字段,非浏览器请求会返回不同内容。改用HttpURLConnection设置请求头,模拟浏览器访问。

3. 解析页面中的JSON数据

YouTube的初始静态页面里,会把视频核心数据(包括播放量)放在名为ytInitialData的JavaScript变量里,我们可以提取这个变量的内容,解析JSON拿到播放量,不需要处理动态渲染的内容。

修改后的完整代码

package Project;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class WebScraper {
    public static void main(String[] args) throws IOException {
        URL website = new URL("https://www.youtube.com/watch?v=9h5JC-GLR6g");
        HttpURLConnection connection = (HttpURLConnection) website.openConnection();
        
        // 设置请求头,模拟Chrome浏览器
        connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36");
        connection.setRequestProperty("Accept-Language", "en-US,en;q=0.9");

        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        StringBuilder pageContent = new StringBuilder();
        String line;

        // 正确读取所有行,避免丢行
        while ((line = in.readLine()) != null) {
            pageContent.append(line);
        }
        in.close();
        connection.disconnect();

        // 提取ytInitialData变量的内容
        Pattern pattern = Pattern.compile("ytInitialData\\s*=\\s*(.*?);\\s*</script>");
        Matcher matcher = pattern.matcher(pageContent.toString());
        if (matcher.find()) {
            String jsonData = matcher.group(1);
            // 从JSON中提取播放量,正式项目建议用Gson/Jackson等JSON库解析
            Pattern viewCountPattern = Pattern.compile("\"viewCount\":\"([^\"]+)\"");
            Matcher viewMatcher = viewCountPattern.matcher(jsonData);
            if (viewMatcher.find()) {
                System.out.println("播放量:" + viewMatcher.group(1));
            } else {
                System.out.println("未找到播放量");
            }
        } else {
            System.out.println("未找到ytInitialData");
        }
    }
}

补充说明

  • 正式项目中,建议使用JSON解析库(比如Gson、Jackson)处理ytInitialData的JSON内容,正则匹配容易因页面结构变化失效;
  • YouTube页面结构可能随时调整,若上述方法失效,需重新检查页面数据存储位置;
  • 频繁爬取可能触发反爬机制,建议控制请求频率,遵守网站robots.txt规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 13:55:13