2010-05-14 10 views
41

Ну, я очень стараюсь выяснить, как извлекать информацию с веб-страницы и переносить ее в мою программу (на Java).Как «сканировать» веб-сайт (или страницу) для получения информации и вносить его в мою программу?

Например, если я знаю точную страницу, я хочу получить информацию, для простоты на странице «Лучшая покупка», как мне получить нужную информацию, которая мне нужна, с этой страницы? Как название, цена, описание?

Что бы этот процесс даже назывался? Я понятия не имею, чтобы даже начать исследовать это.

Edit: Хорошо, я бегу тест для JSoup (тот, отправленный 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

+1

You есть проблема с LinkedList, потому что LinkedList.peekFirst появился в java 1.6, и вы, кажется, используете ухо lier version – zamza

+2

Этот процесс обычно называется «скрипинг экрана» и используется, когда API (например, SOAP) недоступен, но веб-интерфейс. Это связано с тем, что ваше приложение претендует на роль веб-браузера и вручную обрабатывает страницы HTML (более или менее). Я предлагаю вам рассмотреть один из перечисленных ниже API, которые автоматизируют большую часть синтаксического анализа. –

ответ

83

Использовать HTML-парсер, например Jsoup. У меня есть предпочтение выше other HTML parsers available in Java, так как оно supportsjQuery нравится CSS selectors. Кроме того, его класс, представляющий список узлов, Elements, реализует Iterable, так что вы можете перебирать его в enhanced for loop (так что нет необходимости хлопотать с подробными Node и NodeList как классы в среднем парсе Java DOM).

Вот простой пример стартового (просто поставить latest Jsoup JAR file в пути к классам):

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()); 
     } 
    } 

} 

Как вы уже догадались, это печатает свой вопрос и имена всех отвечающими.

+1

Ничего себе, это хорошо! У меня есть вопрос, хотя я просто копировал и вставлял это только для выполнения тестового прогона, но я продолжаю получать эту ошибку (см. Отредактированный OP). – James

+2

@James: для этого требуется хотя бы Java 1.6 (который уже более 3 лет) , Указанный метод [LinkedList # peekFirst() '] (http://java.sun.com/javase/6/docs/api/java/util/LinkedList.html#peekFirst%28%29) был введен в Java 1.6 , Обновите JVM (JDK) или настройте свой IDE (Eclipse?) На режим соответствия Java 6. – BalusC

+8

Если кто-либо из .NET-программистов заинтересован, я портировал jsoup на .NET: http://nsoup.codeplex.com/. Надеюсь, это поможет кому угодно. – GeReV

3

Вы может использовать html-парсер (много полезных ссылок здесь: java html parser).

Этот процесс называется «захват содержимого веб-сайта». Поиск «захватить содержимое веб-сайта java» для дальнейшей инверсии.

-1

Загляните в библиотеку cURL. Я никогда не использовал его в Java, но я уверен, что для него должны быть привязки. В основном, то, что вы сделаете, это отправить запрос cURL на любую страницу, которую вы хотите «очистить». Запрос вернет строку с исходным кодом на страницу. Оттуда вы будете использовать регулярное выражение для анализа любых данных, которые вы хотите получить из исходного кода. В общем, как вы собираетесь это делать.

+3

[Не использовать регулярное выражение для разбора HTML] (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454). – BalusC

9

Это упоминается как скребок экрана, wikipedia содержит эту статью по контенту web scraping. Это может быть серьезной проблемой, потому что там есть какой-то уродливый, беспорядочный, взломанный, если не для браузера, умный HTML, так что удачи.

1

Возможно, вы захотите просмотреть HTML-код, чтобы узнать, можете ли вы найти строки, которые уникальны и рядом с вашим текстом, а затем вы можете использовать линии/char-offsets для доступа к данным.

Может быть неудобно в Java, если нет классов XML, подобных тем, которые были найдены в System.XML.Linq в C#.

4

Сам процесс обычно называется «соскабливанием». Вы можете использовать синтаксический анализатор, например TagSoup, для обработки страницы, как только вы ее извлекли.

4

Я бы использовал JTidy - это simlar для JSoup, но я не знаю JSoup хорошо. JTidy обрабатывает разбитый HTML и возвращает документ w3c, поэтому вы можете использовать это как источник для XSLT для извлечения интересующего вас контента.Если вы не знаете XSLT, то вы также можете пойти с JSoup, так как модель документа лучше работать, чем с w3c.

EDIT: быстрый просмотр веб-сайта JSoup показывает, что JSoup действительно может быть лучшим выбором. Кажется, он поддерживает селектора CSS из коробки для извлечения материала из документа. С этим легче работать, чем с XSLT.

1

решение JSoup велик, но если вам нужно извлечь только то, что на самом деле это просто может быть проще использовать регулярные выражения или String.indexOf

Как и другие уже упоминали процесс называется выскабливание

+0

Почему было бы проще использовать регулярное выражение? Я пробовал регулярное выражение, и он действительно не может обрабатывать html реальной жизни и, возможно, опасно использовать parse html. Jsoup - это нестандартное решение, всего несколько строк кода, и вы делаете то, что когда-либо вам нужно делать с вашим html. – newbie

+0

Пример с упрощенным вариантом - представьте, что все, что вам нужно, - это извлечь дату, когда была сгенерирована страница. Итак, вы проверяете html и видите что-то вроде ' 07/07/07'. Ну, тогда я бы использовал String.indexOf или некоторые из моих собственных утилит, таких как textBetween ("", ""). Дополнительным преимуществом является то, что вам не нужно разбирать весь html. Мне удалось получить данные из html с помощью собственного класса StringScanner с такими методами, как moveBefore (String what), moveAfter (String what), getTextUpTo (String what), ... Все зависит от сложности вашей проблемы. – Anton

1

Вы также можете попробовать jARVEST.

Он основан на JRuby DSL на чистом-Java-движке для веб-сайтов с расширением паутины.

Пример:

Найти все ссылки внутри веб-страницы (wget и xpath являются конструкциями языка jARVEST в):

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); 
    }