Как «Сканировать» сайт (или страницу) для информации и принести его в мою программу?
-
26-09-2019 - |
Вопрос
Ну, я в значительной степени пытаясь выяснить, как вытащить информацию из веб-страницы и принести его в мою программу (в Java).
Например, если я знаю точную страницу, которую я хочу получить информацию, ради простоты Лучший купить страницу товара, как бы я получил соответствующую информацию, которая мне нужна из этой страницы? Как титул, Цена, Описание?
Что бы этот процесс даже будет называться? Я понятия не имею, что даже начать исследовать это.
Редактировать: Хорошо, я запускаю тест для JSUP (один, который размещен BalusC), но я продолжаю получать эту ошибку:
Exception in thread "main" java.lang.NoSuchMethodError: java.util.LinkedList.peekFirst()Ljava/lang/Object;
at org.jsoup.parser.TokenQueue.consumeWord(TokenQueue.java:209)
at org.jsoup.parser.Parser.parseStartTag(Parser.java:117)
at org.jsoup.parser.Parser.parse(Parser.java:76)
at org.jsoup.parser.Parser.parse(Parser.java:51)
at org.jsoup.Jsoup.parse(Jsoup.java:28)
at org.jsoup.Jsoup.parse(Jsoup.java:56)
at test.main(test.java:12)
У меня есть Apache Commons
Решение
Используйте анализатор HTML, как Jsououp.. Отказ Это имеет мои предпочтения выше Другие фарсы HTML доступны в Java с тех пор поддерживает jquery подобно CSS селекторы. Отказ Кроме того, его класс, представляющий список узлов, Elements
, реализация Iterable
так что вы можете перейти на него в Улучшено для петли (так что нет необходимости хлопотать с Verbose Node
а также NodeList
Как классы в среднем Java Dom Parser).
Вот базовый пример покрова (просто положи Последний файл JSUP JAR В классе):
package com.stackoverflow.q2835505;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class Test {
public static void main(String[] args) throws Exception {
String url = "https://stackoverflow.com/questions/2835505";
Document document = Jsoup.connect(url).get();
String question = document.select("#question .post-text").text();
System.out.println("Question: " + question);
Elements answerers = document.select("#answers .user-details a");
for (Element answerer : answerers) {
System.out.println("Answerer: " + answerer.text());
}
}
}
Как вы, возможно, догадались, это печатает ваш собственный вопрос и имена всех ответов.
Другие советы
Это называется Scraping экрана, У Википедии есть эта статья о более конкретной Веб-соскоб. Отказ Это может быть серьезной проблемой, потому что есть несколько уродливых, потрясающих, сломанных - если нет для браузера-умного HTML там, так удачи.
я хотел бы использовать Jtidy. - Это Симлар в jsououp, но я не знаю jsououp хорошо. JTIDY обрабатывает сломанный HTML и возвращает документ W3C, поэтому вы можете использовать это в качестве источника к XSLT, чтобы извлечь контент, который вы действительно заинтересованы в. Если вы не знаете XSLT, то вы могли бы также пойти с JSUP, как документ Модель приятнее работать с чем W3C.
Редактировать: Быстрый поиск на веб-сайте JSUP показывает, что JSUP действительно может быть лучшим выбором. Кажется, он поддерживает селекторы CSS из коробки для извлечения материала из документа. Это может быть намного легче работать с чем попасть в XSLT.
Вы можете использовать Parser HTML (здесь много полезных ссылок: Java HTML Parser.).
Процесс называется «Содержание сайта Grabbing». Поиск «GRAB-сайт содержимого Java» для дальнейшей обратной связи.
JSUP поддерживает Java 1.5
https://github.com/tburch/jsoup/commit/d8ea84f46e009a7f144ee414a9fa73ea187019a3.
Похоже, этот стек был ошибкой, и был исправлен
Решение JSUP отлично, но если вам нужно сделать что-то действительно просто, может быть проще использовать Regex или String.indexof
Как другие уже упомянули, процесс называется соскоб
Вы, вероятно, хотите посмотреть HTML, чтобы увидеть, сможете найти строки, которые являются уникальными и рядом с вашим текстом, вы можете использовать строку / Char-Offsets, чтобы добраться до данных.
Может быть неловко в Java, если нет никаких классов XML, аналогичных, найденных в System.XML.Linq
в C #.
Вы также можете попробовать жаркий.
Он основан на JRuby DSL по поводу двигателя чистого Java до веб-сайтов Spider-Scrape-Transform.
Пример:
Найти все ссылки внутри веб-страницы (wget
а также xpath
являются конструкциями языка Яржа):
wget | xpath('//a/@href')
Внутри программы Java:
Jarvest jarvest = new Jarvest();
String[] results = jarvest.exec(
"wget | xpath('//a/@href')", //robot!
"http://www.google.com" //inputs
);
for (String s : results){
System.out.println(s);
}
Мой ответ, вероятно, не будет полезен для автор этого вопроса (мне позже мне 8 месяцев, поэтому не правильное время, которое я думаю), но я думаю, что это, вероятно, будет полезно для многих других разработчиков, которые могут столкнуться с этим ответом.
Сегодня я только что выпустил (во имя моей компании) HTML To Pojo полную структуру, которую вы можете использовать для карты HTML к любому классу POJO, просто некоторые аннотации. Сама библиотека вполне удобна и имеет много других вещей, которые все время будут очень подключаемыми. Вы можете посмотреть на это прямо здесь: https://github.com/whimtrip/jwht-htmltopojo
Как использовать: Основы
Представьте, что нам нужно разбирать следующую HTML-страницу:
<html>
<head>
<title>A Simple HTML Document</title>
</head>
<body>
<div class="restaurant">
<h1>A la bonne Franquette</h1>
<p>French cuisine restaurant for gourmet of fellow french people</p>
<div class="location">
<p>in <span>London</span></p>
</div>
<p>Restaurant n*18,190. Ranked 113 out of 1,550 restaurants</p>
<div class="meals">
<div class="meal">
<p>Veal Cutlet</p>
<p rating-color="green">4.5/5 stars</p>
<p>Chef Mr. Frenchie</p>
</div>
<div class="meal">
<p>Ratatouille</p>
<p rating-color="orange">3.6/5 stars</p>
<p>Chef Mr. Frenchie and Mme. French-Cuisine</p>
</div>
</div>
</div>
</body>
</html>
Давайте создадим Pojos, мы хотим сопоставить его:
public class Restaurant {
@Selector( value = "div.restaurant > h1")
private String name;
@Selector( value = "div.restaurant > p:nth-child(2)")
private String description;
@Selector( value = "div.restaurant > div:nth-child(3) > p > span")
private String location;
@Selector(
value = "div.restaurant > p:nth-child(4)"
format = "^Restaurant n\*([0-9,]+). Ranked ([0-9,]+) out of ([0-9,]+) restaurants$",
indexForRegexPattern = 1,
useDeserializer = true,
deserializer = ReplacerDeserializer.class,
preConvert = true,
postConvert = false
)
// so that the number becomes a valid number as they are shown in this format : 18,190
@ReplaceWith(value = ",", with = "")
private Long id;
@Selector(
value = "div.restaurant > p:nth-child(4)"
format = "^Restaurant n\*([0-9,]+). Ranked ([0-9,]+) out of ([0-9,]+) restaurants$",
// This time, we want the second regex group and not the first one anymore
indexForRegexPattern = 2,
useDeserializer = true,
deserializer = ReplacerDeserializer.class,
preConvert = true,
postConvert = false
)
// so that the number becomes a valid number as they are shown in this format : 18,190
@ReplaceWith(value = ",", with = "")
private Integer rank;
@Selector(value = ".meal")
private List<Meal> meals;
// getters and setters
}
И сейчас Meal
класс, а также:
public class Meal {
@Selector(value = "p:nth-child(1)")
private String name;
@Selector(
value = "p:nth-child(2)",
format = "^([0-9.]+)\/5 stars$",
indexForRegexPattern = 1
)
private Float stars;
@Selector(
value = "p:nth-child(2)",
// rating-color custom attribute can be used as well
attr = "rating-color"
)
private String ratingColor;
@Selector(
value = "p:nth-child(3)"
)
private String chefs;
// getters and setters.
}
Мы предоставили еще несколько объяснений по вышеуказанному коду на нашей странице GitHub.
На данный момент давайте посмотрим, как ловить это.
private static final String MY_HTML_FILE = "my-html-file.html";
public static void main(String[] args) {
HtmlToPojoEngine htmlToPojoEngine = HtmlToPojoEngine.create();
HtmlAdapter<Restaurant> adapter = htmlToPojoEngine.adapter(Restaurant.class);
// If they were several restaurants in the same page,
// you would need to create a parent POJO containing
// a list of Restaurants as shown with the meals here
Restaurant restaurant = adapter.fromHtml(getHtmlBody());
// That's it, do some magic now!
}
private static String getHtmlBody() throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(MY_HTML_FILE));
return new String(encoded, Charset.forName("UTF-8"));
}
Другой короткий пример можно найти здесь
Надеюсь, это поможет кому-то там!
Посмотрите в библиотеку скручиваемости. Я никогда не использовал его в Java, но я уверен, что для него должны быть привязки. В основном, что вы будете делать, это отправьте запрос скручиваемости на любую страницу, которую вы хотите «Scrape». Запрос вернет строку с исходным кодом на страницу. Оттуда вы будете использовать Regex для анализа любых данных, которые вы хотите из исходного кода. Это как правило, как вы собираетесь это сделать.