#java #css-selectors #html-parsing #jsoup
#java #css-селекторы #html-синтаксический анализ #jsoup
Вопрос:
Я пытаюсь выбрать информационное поле на странице ввода Google в Википедии: http://en.m.wikipedia.org/wiki/Google
Итак, я вызываю:
contentDiv = document.select("div[id=content]").first();
Который работает, как и ожидалось, тогда я делаю:
Elements infoboxes = contentDiv.select("table[class=infobox]");
Затем я проверяю infoboxes.isEmpty()
, и я ошеломлен, обнаружив, что он пуст!
Я проверил и убедился, что элемент contentDiv
содержит следующее:
<table class="infobox vcard" style="width: 22em;" cellspacing="5">
Итак, почему contentDiv.select("table[class=infobox]")
возвращает пустой???
ОБНОВЛЕНИЕ: я протестировал вышеуказанное, contentDiv.select("table[class=infobox vcard]")
и оно отлично работает! Это странно, поскольку я знаю, что в отличие от table.infobox.vcard
обозначения, которое выбирает только точный многоклассовый элемент, table[class=infobox]
следует выбирать все таблицы, которые имеют по крайней мере infobox
в их перечисленных классах.
Кстати, я протестировал код с другой записью в Википедии, содержащей:
<table class="infobox biota" style="text-align: left; width: 200px; font-size: 100%;">
И это contentDiv.select("table[class=infobox]")
ведет себя точно так, как ожидалось, возвращая этот элемент таблицы в качестве первого элемента infoboxes
.
Есть идеи, почему несоответствие? Что может объяснить это странное поведение?
Возможно ли, что я просто наткнулся на ошибку Jsoup?
(Я использую jsoup-1.5.2, не последнюю версию, но мне не нужна поддержка HTML5, и по разным причинам я не могу сразу перейти на последнюю версию 1.6.1).
Ответ №1:
[attributename=attributevalue]
Селектор точно соответствует. Это указано в спецификации селектора CSS (выделение мое):
[att=val]
Совпадение, когда значение атрибута элемента «att» точно равно «val».
Вы хотите использовать [attributename~=attributevalue]
вместо:
Elements infoboxes = contentDiv.select("table[class~=infobox]");
// ...
или, что еще лучше, .classname
селектор:
Elements infoboxes = contentDiv.select("table.infobox");
// ...
Смотрите также:
- Спецификация селектора CSS — селекторы атрибутов — селекторы классов
- Кулинарная книга селектора Jsoup
- Jsoup
Selector
API
Что касается вашего теста с другой записью в Википедии, я не могу воспроизвести это. Но я могу сказать, что эта страница содержит другую <table class="infobox">
, которая должна быть той, которую вы на самом деле извлекаете.
Комментарии:
1. Я, должно быть, идиот: все это время я обращал внимание на фундаментальную разницу между
tag.["class=classname"]
( точным совпадением) обозначением иtag.classname
(неточная) нотация, но я поменял их местами, а затем потратил слишком много времени на выяснение того, что происходит. 25.