«Умный» способ парсинга и использования данных сайта? - PullRequest
31 голосов
/ 03 августа 2009

Как можно интеллектуально анализировать данные, возвращаемые результатами поиска на странице?

Например, допустим, я хотел бы создать веб-сервис, который выполняет поиск онлайн-книг, анализируя результаты поиска на сайтах многих поставщиков книг. Я мог бы получить необработанные HTML-данные страницы и выполнить некоторые регулярные выражения, чтобы данные работали для моего веб-сервиса, но если какой-либо из веб-сайтов изменит форматирование страниц, мой код будет поврежден!

RSS - действительно изумительный вариант, но многие сайты не имеют поиска на основе XML / JSON.

Существуют ли какие-либо комплекты, которые помогают автоматически распространять информацию на страницах? Сумасшедшая идея заключалась в том, чтобы нечеткий AI-модуль распознавал шаблоны на странице результатов поиска и соответственно анализировал результаты ...

Ответы [ 12 ]

24 голосов
/ 03 августа 2009

Я сделал кое-что из этого недавно, и вот мой опыт.

Существует три основных подхода:

  1. Регулярные выражения.
    • Самый гибкий, простой в использовании со слабо структурированной информацией и изменяющимися форматами.
    • Сложнее проводить структурный анализ / анализ тегов, но проще сопоставлять текст.
    • Встроенная проверка правильности форматирования данных.
    • Сложнее в обслуживании, чем другие, потому что вам нужно написать регулярное выражение для каждого шаблона, который вы хотите использовать для извлечения / преобразования документа
    • Обычно медленнее, чем 2 и 3.
    • Хорошо работает для списков аналогично отформатированных элементов
    • Хороший инструмент для разработки и тестирования регулярных выражений и несколько примеров страниц помогут. У меня есть что сказать о RegexBuddy. Попробуйте их демо.
    • У меня был самый большой успех с этим. Гибкость позволяет вам работать с неприятным, грубым, диким HTML-кодом.
  2. Преобразование HTML в XHTML и использование инструментов извлечения XML. Очистка HTML, преобразование его в допустимый XHTML и использование XPath / XQuery / X-что угодно для запроса его в виде данных XML.
    • Инструменты: TagSoup, HTMLTidy и т. Д.
    • Качество преобразования HTML в XHML ОЧЕНЬ важно и сильно варьируется.
    • Лучшее решение, если необходимые данные структурированы по макету HTML и тегам (данные в таблицах HTML, списках, группах DIV / SPAN и т. Д.)
    • Наиболее подходит для получения структур ссылок, вложенных таблиц, изображений, списков и т. Д.
    • Должно быть быстрее, чем вариант 1, но медленнее, чем вариант 3.
    • Хорошо работает, если форматирование содержимого изменяется / является переменным, а структура / макет документа - нет.
    • Если данные не структурированы по тегам HTML, у вас проблемы.
    • Может использоваться с вариантом 1.
  3. Генератор парсеров (ANTLR и т. Д.) - создать грамматику для анализа и анализа страницы.
    • Я не пробовал это, потому что это не подходило для моих (грязных) страниц
    • Наиболее подходит, если структура HTML очень структурирована, очень постоянна, регулярна и никогда не меняется.
    • Используйте это, если в документе есть простые для описания шаблоны, но они не включают HTML-теги и предполагают рекурсию или сложные поведения
    • Не требует ввода XHTML
    • БЫСТРАЯ пропускная способность, обычно
    • Большая кривая обучения, но проще в обслуживании

Я возился с веб-сбором для варианта 2, но я нахожу их синтаксис довольно странным. Сочетание XML и некоторого псевдо-Java скриптового языка. Если вам нравится Java, и вам нравится извлечение данных в стиле XML (XPath, XQuery), это может быть для вас идеальным решением.


Редактировать: если вы используете регулярные выражения, убедитесь, что вы используете библиотеку с ленивыми квантификаторами и группами захвата! В старых библиотеках регулярных выражений PHP их нет, и они необходимы для сопоставления данных между тегами открытия / закрытия в HTML.

3 голосов
/ 03 августа 2009

Вы не говорите, какой язык вы используете. В Java Land вы можете использовать TagSoup и XPath, чтобы минимизировать боль. Вот пример из этого блога (конечно, XPath может быть намного сложнее, если того требуют ваши потребности):

URL url = new URL("http://example.com");
SAXBuilder builder = new SAXBuilder("org.ccil.cowan.tagsoup.Parser"); // build a JDOM tree from a SAX stream provided by tagsoup
Document doc = builder.build(url);
JDOMXPath titlePath = new JDOMXPath("/h:html/h:head/h:title");
titlePath.addNamespace("h","http://www.w3.org/1999/xhtml");
String title = ((Element)titlePath.selectSingleNode(doc)).getText();
System.out.println("Title is "+title);

Я бы рекомендовал экстернализацию выражений XPath, чтобы у вас была определенная защита в случае изменения сайта.

Вот пример XPath, который я определенно не использую для скрининга этого сайта. Нет, не я:

"//h:div[contains(@class,'question-summary')]/h:div[@class='summary']//h:h3"
3 голосов
/ 03 августа 2009

Без исправленной структуры HTML для разбора, я бы не хотел поддерживать регулярные выражения для поиска данных. Возможно, вам больше повезет, анализируя HTML через правильный синтаксический анализатор, который создает дерево. Затем выберите элементы ... которые будут более удобными для обслуживания.

Очевидно, что лучший способ - это вывод XML из движка с фиксированной разметкой, который вы можете анализировать и проверять. Я думаю, что HTML-библиотека для разбора с некоторым «в темноте» зондированием созданного дерева будет проще поддерживать, чем регулярные выражения.

Таким образом, вам просто нужно проверить, <a href="blah" class="cache_link">... превращается в <a href="blah" class="cache_result">... или что-то еще.

В итоге, поиск определенных элементов с помощью регулярного выражения будет мрачным. Лучшим подходом является создание DOM-подобной модели страницы и поиск «привязок» к символьным данным в тегах.

Или отправьте электронное письмо на сайт с заявлением о применении XML API ... вас могут нанять!

2 голосов
/ 03 августа 2009

Он не защищен от ошибок, но вы можете захотеть взглянуть на такой синтаксический анализатор, как Beautiful Soup Он не будет волшебным образом находить ту же информацию при изменении макета, но это намного проще, чем писать сложные регулярные выражения , Обратите внимание, что это модуль Python.

2 голосов
/ 03 августа 2009

Вы не упомянули, какой технологический стек вы используете. Если вы разбираете HTML, я бы использовал библиотеку для разбора:

Есть также веб-сервисы, которые делают именно то, что вы говорите - коммерческие и бесплатные. Они очищают сайты и предлагают интерфейсы веб-сервисов.

И универсальный веб-сервис, который предлагает некоторую очистку экрана, - это Yahoo Pipes. предыдущий вопрос stackoverflow по этому вопросу

1 голос
/ 03 августа 2009

Попробуйте поискать в поиске по экрану + язык, который вы предпочитаете. Я знаю несколько вариантов Python, вы можете найти эквивалент для вашего предпочтительного языка:

  • Красивый суп
  • Механизация: аналогично Perl WWW: Механизация. Предоставляет вам подобный браузеру объект для взаимодействия с веб-страницами
  • lxml: привязка python к libwww
  • Scrapemark: использует шаблоны для очистки фрагментов страниц
  • pyquery: позволяет выполнять запросы jQuery в документах xml / xhtml
  • scrapy: фреймворк высокого уровня для сканирования и веб-сканирования для написания пауков для сканирования и анализа веб-страниц

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

1 голос
/ 03 августа 2009

К сожалению, «очистка» является наиболее распространенным решением, как вы сказали, пытаясь анализировать HTML с веб-сайтов. Вы можете обнаружить структурные изменения на странице и пометить предупреждение для исправления, поэтому изменение в их конце не приведет к ошибочным данным. Пока семантическая сеть не станет реальностью, это практически единственный способ гарантировать большой набор данных.

В качестве альтернативы вы можете придерживаться небольших наборов данных, предоставляемых API. Yahoo очень усердно работает над предоставлением данных для поиска через API (см. YDN), я думаю, что Amazon API открывает много книжных данных и т. Д. И т. Д.

Надеюсь, это немного поможет!

РЕДАКТИРОВАТЬ: И если вы используете PHP, я бы порекомендовал SimpleHTMLDOM

1 голос
/ 03 августа 2009

Вы изучали использование библиотеки html-манипуляций? У Руби есть несколько очень хороших. например, hpricot

С хорошей библиотекой вы можете указать нужные части страницы, используя селекторы CSS или xpath. Это было бы намного надежнее, чем использование регулярных выражений.

Пример из hpricot wiki:

 doc = Hpricot(open("qwantz.html"))
 (doc/'div img[@src^="http://www.qwantz.com/comics/"]')
   #=> Elements[...]

Я уверен, что вы можете найти библиотеку, которая делает подобные вещи в .NET или Python и т. Д.

0 голосов
/ 21 октября 2010

Как уже говорили другие, вы можете использовать анализатор HTML, который создает представление DOM и запрашивает его с помощью XPath / XQuery. Я нашел очень интересную статью здесь: теория и практика Java: скриншот с помощью XQuery - http://www.ibm.com/developerworks/xml/library/j-jtp03225.html

0 голосов
/ 24 сентября 2009

Петрушка на http://www.parselets.com выглядит довольно гладко.

Он позволяет вам определять «parslets» с помощью JSON того, что вы определяете, что искать на странице, а затем анализирует эти данные для вас.

...