Получение данных с веб-страницы стабильным и эффективным способом

11

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

Поэтому мой вопрос прост: что же является лучшим / наиболее эффективным и в целом стабильным способом получения этих данных?

Я должен отметить, что:

  • Там нет API
  • Нет другого источника, откуда я могу получить данные (нет баз данных, каналов и т. Д.)
  • Нет доступа к исходным файлам. (Данные с общедоступных сайтов)
  • Допустим, данные представляют собой обычный текст, отображаемый в виде таблицы на html-странице

В настоящее время я использую python для своего проекта, но решение / советы, не зависящие от языка, было бы неплохо.

В качестве побочного вопроса: как бы вы поступили, когда веб-страница создается с помощью Ajax-вызовов?

РЕДАКТИРОВАТЬ:

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

Майк
источник
8
Не существует стабильного способа, независимо от того, как вы реализуете свой скребинг, он может легко сломаться при простом изменении веб-страницы. Стабильный способ получить ваши данные - связаться с авторами данных и заключить сделку для вас, чтобы получить данные в нормальном формате. Иногда это даже не стоит денег.
Иоахим Зауэр
1
@JoachimSauer - на вопрос все еще можно ответить «лучшим» методом.
Аноним
Поскольку большинство веб-сайтов являются динамическими и хранят свои данные в базах данных, лучшим способом является получение базы данных с веб-сайта. Если на сайте есть API, вы можете использовать его. Если вы хотите очистить статические страницы, тогда хорошо работают встроенные модули Python urllib и HTMLParser. Несколько пакетов для очистки HTML также доступны на PyPi.
Ubermensch
Соскоб сайта - это нелегкий бизнес. На самом деле не существует стабильного способа сделать это, потому что владельцы сайтов не хотят, чтобы вы этого хотели, и отрасль в целом пытается помешать людям делать это.
Стивен Эверс
1
Может быть, встроить веб-браузер, такой как Webkit, а затем использовать сценарии DOM для получения информации с отображаемой страницы? Почти каждая платформа может сделать это, но вот как вы это сделаете в Qt: doc.qt.nokia.com/4.7-snapshot/qtwebkit-bridge.html
user16764

Ответы:

2

Ну, вот мои 2 цента:

Если AJAX не задействован или его можно легко очистить, «исправьте» HTML в XHTML (например, с использованием HTMLTidy), а затем используйте XPath вместо регулярных выражений для извлечения информации.
На хорошо структурированной веб-странице логически разделенные объекты информации находятся в разных <div>тегах или в любом другом теге, что означает, что вы сможете легко найти нужную информацию с помощью простого выражения XPath. Это также хорошо, потому что вы можете протестировать его, скажем, в консоли Chrome или в консоли разработчика Firefox и проверить, работает ли он, прежде чем писать хотя бы одну строку другого кода.
Этот подход также имеет очень высокое отношение сигнал / шум, поскольку обычно выражения для выбора соответствующей информации будут однострочными. Их также легче читать, чем регулярные выражения, и они предназначены для этой цели.

Если на странице задействован AJAX и серьезный JavaScript-код, вставьте в приложение компонент браузера и используйте его DOM для запуска нужных вам событий, а XPath - для извлечения информации. Существует множество хороших встраиваемых компонентов браузера, большинство из которых используют реальные браузеры изнутри, и это хорошо, поскольку веб-страница может быть неправильным (X) HTML, но все равно хорошо работать во всех основных браузерах ( на самом деле, большинство страниц в конечном итоге получают этот путь).

K.Steff
источник
Спасибо, я обязательно еще посмотрю на XPath. Я не привык работать с этим, поэтому учиться будет приятно. +1 :)
Майк
5

По моему опыту, используя среду .NET, вы можете воспользоваться преимуществами HTML Agility Pack .

Если страница отформатирована как XHTML, вы также можете использовать обычный анализатор XML. Там много всего для любой среды, которую вы можете себе представить.

Что касается побочного вопроса об AJAX, вы можете использовать обычный сетевой код HTTP для получения и анализа данных.

Опять же, если ваш стек AJAX возвращает XML, у вас есть много вариантов. Если он возвращает JSON, рассмотрим библиотеку, которая позволяет сопоставить поток типизированным объектам. В .NET я предлагаю вам Newtonsoft.Json .

gsscoder
источник
И под «сетевым кодом HTTP» вы подразумеваете захват ответа сервера при выполнении запроса? Спасибо за предложения, я обязательно посмотрю их. +1
Майк
Точно. В .NET вы можете использовать System.Net.WebClient или библиотеку, как RestSharp | restsharp.org . Я использовал это также на Mono для Droid.
gsscoder
4

Разбор HTML - не совсем тривиальная задача, так как приходится иметь дело с, возможно, неправильной разметкой (теговым супом). В течение многих лет браузеры применяли более или менее одну и ту же стратегию для устранения ошибок, и этот алгоритм был назван в спецификации HTML5 (да, спецификация HTML5 определяет, что делать с вещами, которые не являются HTML5).

Это библиотеки для всех основных языков для анализа HTML, например, этот .

В любом случае, то, что вы получите, не является стабильным в любом смысле. Каждый раз, когда формат веб-страницы изменяется, вы должны адаптировать свой скребок.

Andrea
источник
Спасибо, я использовал Beautiful Soup, чтобы сделать работу. Я знаю, что это не будет стабильным, я, вероятно, должен уточнить это в моих вопросах. +1 для вас :)
Майк
4

В качестве побочного вопроса: как бы вы поступили, когда веб-страница создается с помощью Ajax-вызовов?

Если выполняются ajax-вызовы, то, скорее всего, это либо POST, либо GET url с некоторыми переменными.

Я бы изучил JavaScript, чтобы узнать, каковы конечные точки и параметры. После этого очень вероятно, что либо возвращенные данные будут в формате json / xml / plain text, либо, возможно, частичным html.

Как только вы узнаете вышеупомянутую информацию, вы просто делаете запрос GET или POST к этой конечной точке и анализируете возвращенные данные.

Темная ночь
источник
2
Стоит отметить, что многие службы проверяют заголовки HTTP, чтобы убедиться, что HTTP_X_REQUESTED_WITHэто XMLHttpRequest. Хорошие также реализуют некоторую защиту XSRF для POST-запросов, поэтому вам понадобится и этот волшебный cookie. Щекотание конечных точек AJAX, не преднамеренно представленных каким-либо общедоступным API, кажется мне немного странным, и ваш скребок так же склонен к поломке, если выходные данные (или политика запросов) изменятся.
Тим Пост
@TimPost ты на 100% прав. Я согласен, что это действительно "неприглядно" :), но в отсутствие какого-либо общедоступного API, необходимо ...
Darknight
Я мог бы использовать это в своем собственном приложении, работающем на AJAX (и под «собственным» я не имею в виду, что написал это, но настройки мои), но было бы неправильно пытаться обойти систему другого сервера, поэтому я должен согласиться с @ TimPost, это выглядит как-то "неприлично". Это хорошая идея, однако, спасибо! +1!
Майк
1

Не существует стабильного или лучшего способа сделать это, веб-страницы HTML не были созданы для управления компьютерами. Он предназначен для пользователей, но если вам нужно сделать это, я предлагаю использовать браузер и некоторый JavaScript. На моей работе я был связан с проектом, который должен извлечь некоторую информацию со стороннего сайта. Приложение было разработано как расширение Chrome. Логика приложения написана с использованием JavaScript, который добавляется на сайт после завершения загрузки страницы. Извлеченные данные отправляются в базу данных через http-сервер. Это не лучший подход, но он работает. Ps: Владелец сайта разрешил нам делать такие вещи.

NOHROS
источник
Я знаю, что HTML-страницы не должны анализироваться компьютерами, но иногда просто нет другого выхода. Кроме того, я использую общедоступную информацию для личного проекта, который никоим образом не является коммерческим, я не думаю, что мне нужно явное разрешение, не так ли? Спасибо за ваш вклад! +1 для вас тоже;)
Майк
@MikeHeremans Чтобы узнать, авторизованы ли вы для получения информации с веб-сайта, прочитайте ToS и robots.txt. Если оба не откажут вам в праве автоматически очищать информацию, вы, вероятно, должны быть в порядке в большинстве случаев на законных основаниях. Конечно, IANAL ...
К.Стефф
Если вы хотите увидеть код упомянутого проекта: code.google.com/p/acao-toolkit/source/browse/… . Проверьте content_script.js, это код, который вводится на странице.
nohros