Jsoup не работает должным образом с закодированной ссылкой, содержащей не буквенные символы - PullRequest
4 голосов
/ 24 мая 2019

Я создаю несогласованного бота для онлайн-игры, и одна из функций ботов - использование веб-сканера для получения информации об элементе.

Моя проблема заключается в том, что при использовании URL-адреса в кодировке UTF-8 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

Например, url: http://coryn.club/item.php?name=dark+general будет работать полностью, а URL http://coryn.club/item.php?name=dark+general%27s - нет.Единственное отличие -% 27 в конце.

Я получаю нулевое значение с элементом класса "table table-striped".

Просто чтобы заметить, что я использую тот же кодв обоих URL, но работает только первый.

Также отметим, что если вы откроете страницу в браузере, она будет работать, и вы все равно увидите данные HTML с элементом inspect.

1 Ответ

3 голосов
/ 25 мая 2019

Похоже, что если вы используете необработанные (не кодированные) данные запроса, такие как

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, например String, например List<String>, поскольку 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-эквивалент взрыва PHP (',', array_filter (array ()))

...