Подключение к шведской Википедии для извлечения информации
Что мне нужно сделать, так это подключиться к Википедии и извлечь текст в области над списком с содержимым, а также, если возможно, информацией (см. Рисунок ниже). Есть несколько вариантов: JWPL, Bliki, JSoup.
Я попробовал Блики, но не смог получить информацию (см. Рисунок) и не смог перейти на шведский. JSoup кажется довольно простым, однако, поскольку он не предназначен специально для википедии, не существует простого способа получить контент на странице, которую я ищу.
Используя JSoup, я могу очень легко получить HTML-документ, но не могу понять, как получить только ту часть, которую я хочу, в виде простого текста.
Document doc = Jsoup.connect("http://sv.wikipedia.org/wiki/Stockholm").get();
Element contentDiv = doc.select("div[id=content]").first();
System.out.println(contentDiv.toString());
Используя этот код Bliki, вы получите документ, отформатированный в виде простого текста, и это здорово, однако в него не входит информация из рисунка ниже. И самое главное не на шведском, потому что я не знаю, как это изменить.
String[] listOfTitleStrings = { "Stockholm" };
User user = new User("", "", "http://en.wikipedia.org/w/api.php");
user.login();
List<Page> listOfPages = user.queryContent(listOfTitleStrings);
PlainTextConverter p = new PlainTextConverter();
for (Page page : listOfPages) {
WikiModel wikiModel = new WikiModel("${image}","${title}");
String text = wikiModel.render(p, page.toString());
System.out.println(text);
}
Будет работать на Android. Редактировать: Может быть, я не достаточно ясно, что это должно работать на всех страницах Википедии.
1 ответ
Я сомневаюсь, что вы получите то, что ищете, просто скопировать и вставить. JSoup - это анализатор HTML, вам придется искать элементы и писать соответствующие селекторы, чтобы получить их содержимое.
Если вы используете Chrome, щелкните правой кнопкой мыши по элементу (тексту) и выберите элемент проверки, и как только откроется источник HTML, щелкните правой кнопкой мыши соответствующий элемент и выберите Copy CSS Path
,
Для Country (Land) вы получите что-то вроде этого:
#mw-content-text > table.infobox.geography > tbody > tr:nth-child(5) > td > span > a
Конечно, это можно сократить, но это не сильно улучшит производительность, и это будет проблемой, если вы недостаточно хорошо знаете CSS.
К счастью, JSoup поддерживает CSS-селекторы, так что вы можете сделать после того, как получите соответствующий элемент:
String countrySelector = "#mw-content-text > table.infobox.geography > tbody > tr:nth-child(5) > td > span > a";
Document doc = Jsoup.connect("http://sv.wikipedia.org/wiki/Stockholm").get();
Element countryEl = doc.select(countrySelector).first();
System.out.println(countryEl.toString());
(Я предполагаю, что предоставленный вами код работает правильно)
Если вы хотите проверить правильность выбора селектора, вы можете сделать это непосредственно в Chrome, после того, как вы скопировали селектор, измените вкладку на Console
затем используйте $("selector")
, затем нажмите Enter, например:
$("#mw-content-text > table.infobox.geography > tbody > tr:nth-child(5) > td > span > a")
Если вам нужно текстовое содержимое элемента, вы можете использовать $("selector").text()
,
(Возможно, вы заметили, что это простой jQuery)
Но будьте осторожны, это может легко сломаться, если Википедия решит обновить свой макет DOM.
Изменить: (добавив это после дополнительного пояснения в комментариях)
Чтобы селекторы работали на нескольких страницах, вы можете сделать их более общими.
Первое, что нужно выбрать, это infobox
справа, лучше всего использовать table.infobox
, но это все равно может выбрать более одного элемента. Информация, которую вы запрашиваете, обычно находится в первом информационном блоке, поэтому ее легко выбрать с помощью .first()
, Если это не сработает и вы не найдете нужный элемент, вы можете создать запасной вариант, чтобы попытаться найти информацию во всех элементах инфобокса.
Я до сих пор не уверен, что именно вы ищете, так что вот код, который вы должны получить при соединении выше:
// Set infobox selector (content on the right side of Wiki page)
String tableSelector = "table.infobox";
// Load document
Document doc = Jsoup.connect("http://en.wikipedia.org/wiki/Gothenburg").get();
// Select infobox element
Element infoboxEl = doc.select(tableSelector).first();
// Select all table rows inside infobox
Elements tableRows = infoboxEl.select("tr");
for (Element row: tableRows) {
// Output the title of each row
System.out.print(row.select("th").text() + ": ");
// Output conent for that title
System.out.println(row.select("td").text());
}
Вот пример вывода:
Gothenburg, Sweden Göteborg:
_: From left to right: View over Gothenburg and the Göta älv, Götaplatsen, Svenska Mässan, Gothenburg heritage tram, Elfsborg Fortress, Ullevi.
_: Nickname(s): Little London Little Amsterdam,
_: Gothenburg, Sweden
_: Coordinates: 57°42′N 11°58′E / 57.700°N 11.967°E / 57.700; 11.967Coordinates: 57°42′N 11°58′E / 57.700°N 11.967°E / 57.700; 11.967
Country: Sweden
Province: Västergötland and Bohuslän
County: Västra Götaland County
Municipality: Gothenburg Municipality, Härryda Municipality, Partille Municipality and Mölndal Municipality
Charter: 1621
Area[1]:
• City: 447.76 km2 (172.88 sq mi)
• Water: 14.5 km2 (5.6 sq mi) 3.2%
• Urban: 203.67 km2 (78.64 sq mi)
• Metro: 3,694.86 km2 (1,426.59 sq mi)
Elevation: 12 m (39 ft)
Population (2013 (urban: 2010))[1][2]:
• City: 533,260
• Density: 1,200/km2 (3,100/sq mi)
• Urban: 549,839
• Urban density: 2,700/km2 (7,000/sq mi)
• Metro: 956,118
• Metro density: 260/km2 (670/sq mi)
Demonym: Gothenburger (Göteborgare)
Time zone: CET (UTC+1)
• Summer (DST): CEST (UTC+2)
Postal code: 40xxx - 41xxx - 421xx - 427xx
Area code(s): (+46) 31
Website: www.goteborg.se
Это выводит на экран все, что вы можете увидеть в вики, и может быть не совсем тем, что вы хотите, так как в некоторых случаях отсутствуют заголовки (отмечены как _:
). Но я думаю, вы поняли, как это работает, и вы можете использовать это, чтобы отфильтровать то, что вы ищете.
Я бы порекомендовал вам использовать класс, чтобы сохранить эти данные и отобразить их в вашем приложении позже. Таким образом, вы можете легко применить логику, которая будет проверять, получили ли вы все правильные данные, и если они не удастся, вы можете создать запасной вариант, чтобы исправить это.