【问题标题】:Jsoup doesn't work properly with encoded link containing non-letter charactersJsoup 不适用于包含非字母字符的编码链接
【发布时间】:2019-05-24 19:53:48
【问题描述】:

我正在为在线游戏创建一个不和谐机器人,其中一个机器人的功能是使用网络爬虫获取物品信息。

我的问题是,当我使用 UTF-8 编码的 URL 时,Jsoup 由于某种原因无法正常工作。

我确实尝试遍历具有相同类名的所有元素,但这根本不起作用。那里似乎完全没有班级。

String url = "http://coryn.club/item.php?name=";

StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(arguments.get(0));

for (int i = 1; i < arguments.size(); i++)
    stringBuilder.append(" ").append(arguments.get(i));

url = url + URLEncoder.encode(stringBuilder.toString(), "UTF-8");
System.out.println(url);
Document document = Jsoup.connect(url).get();
Element table = document.getElementsByClass("table table-striped").first();
System.out.println(table == null ? "Table is null" : "Table is not null"); //returns that the table is null only on the %27 link

例如,网址:http://coryn.club/item.php?name=dark+general 完全可以使用,但网址http://coryn.club/item.php?name=dark+general%27s 则不行。唯一的区别是接近尾声的 %27。

我确实得到了一个带有“table table-striped”类元素的空值。

请注意,我在两个 URL 中使用相同的代码,但只有第一个有效。

还要注意,如果您确实在浏览器中打开该页面,它会起作用,并且您仍然会看到带有检查元素的 HTML 数据。

【问题讨论】:

    标签: java jsoup


    【解决方案1】:

    如果您使用原始(未编码)查询数据,例如

    String url = "http://coryn.club/item.php?name=dark general's";
    

    你会得到正确的结果。

    这表明 Jsoup 自己对这些参数进行编码,这意味着如果您使用 dark+general%27s 形式的数据,它将再次被编码,导致最终 URL 包含 dark%2Bgeneral%2527s

    由于该服务器在解码后会将name 的值视为dark+general%27s 而不是dark general's,并且将搜索并找不到与其匹配的结果。因此,返回的 HTML 中不会有结果表。

    所以不要对您的数据进行编码,让 Jsoup 为您完成


    顺便说一句:您还可以将代码更改为更多(IMO)可读版本

    Document document = Jsoup
            .connect("http://coryn.club/item.php")
            .data("name", stringBuilder.toString()) //query parameters - don't encode manually
            .get();
    

    注意stringBuilder.toString()不是我们编码的,它包含像dark general's这样的原始数据。


    顺便说一句 2:如果 arguments 被定义为包含类似字符串的 CharacterSequence,例如 List&lt;String&gt;,因为 Java 8 而不是

    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(arguments.get(0));
    
    for (int i = 1; i < arguments.size(); i++)
        stringBuilder.append(" ").append(arguments.get(i));
    

    你可以使用

    String joined = String.join(" ", arguments);
    

    String joined = arguments.stream().collect(Collectors.joining(" "));
    

    更多信息:Java equivalent of PHP's implode(',' , array_filter( array () ))

    【讨论】:

      猜你喜欢
      • 2019-08-26
      • 1970-01-01
      • 2020-12-24
      • 2017-07-05
      • 1970-01-01
      • 2021-02-22
      • 1970-01-01
      • 1970-01-01
      • 2016-10-29
      相关资源
      最近更新 更多