如何使用 Jsoup (Java) 检索 Youtube 的自动完成结果?

How do I retrieve Youtube's autocomplete results using Jsoup (Java)?

如图所示,我想使用 Jsoup 检索自动完成搜索结果。我已经在使用视频 ID 检索视频 URL、视频标题和缩略图,但我无法从搜索结果中检索它们。

我必须在不使用 Youtube 的数据 Api 且仅使用 Jsoup 的情况下完成此操作。

任何能为我指明正确方向的建议都将不胜感激。

搜索结果是通过 JavaScript 动态生成的。这意味着它们不能被 Jsoup 解析,因为 Jsoup 只是 "sees" 页面中嵌入的静态代码。但是,我们可以直接从 API 中获取结果。

YouTube 的自动完成搜索结果是从网络服务(由 Google 提供)获取的。每次我们在搜索栏中添加一个字母时,都会在后台向该服务发出请求,并在页面上呈现响应。我们可以使用浏览器的开发者工具发现这样的 APIs。例如,我通过以下过程找到了这个 API:

  • 在浏览器中打开 YouTube。
  • 打开开发者控制台。 (Ctrl + Shift + I).
  • 转到 Network 选项卡。在这里,我们可以找到有关我们的浏览器与网络服务器的连接的详细信息。
  • 在 YouTube 的搜索栏中添加一个字母。此时,我们可以看到对 https://clients1.google.com/complete/search 的新 GET 请求。
  • 单击该请求并转到右侧的框,我们可以在其中更仔细地检查请求-响应。在 Headers 选项卡中,我们看到 URL 包含我们的搜索查询;在 Response 选项卡中,响应正文包含自动完成结果。

响应是一个 JavaScript 片段,其中包含数组中的数据,可以使用正则表达式对其进行解析。 Jsoup 可用于 HTTP 请求,但任何 HTTP 客户端都可以。

public static ArrayList<String> autocompleteResults(String query) 
        throws IOException, UnsupportedEncodingException, PatternSyntaxException {
    String url = "https://clients1.google.com/complete/search?client=youtube&hl=en&gs_rn=64&gs_ri=youtube&ds=yt&cp=10&gs_id=b2&q=";
    String re = "\[\"(.*?)\",";

    Response resp = Jsoup.connect(url + URLEncoder.encode(query, "UTF-8")).execute();
    Matcher match = Pattern.compile(re, Pattern.DOTALL).matcher(resp.body());

    ArrayList<String> data = new ArrayList<String>();
    while (match.find()) {
        data.add(match.group(1));
    }
    return data;
}

所提供的代码是在 VScode、Java8、Windows 上创建和测试的,但它也应该适用于 Android Studio。