titulusdesiderio
@titulusdesiderio
IT-специалист

Лучший ЯП для парсинга веб-сайтов

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

Какой, по вашему мнению, ЯП (+Фреймворк/библиотека) лучше всего подходит именно для задачи парсинга веб-страниц?
Буду весьма благодарен за аргументированные ответы. А ещё больше за ссылки на статьи по использованию ЯП в этом направлении и/или на репозитории проектов по теме.

Немного о конкретной задаче, над решением которой я работаю: 50+ независимых сайтов (производителей определённых видов продукции), с которых нужно собрать базу их продуктов. Нужно не только 1 раз прогнать, но и повторять прогон хотя бы раз в день, или при появлении новых продуктов (а следовательно и дописывать код при появлении новых особенностей у новых продуктов). Ввиду большого количества сайтов (которое со временем будет только увеличиваться) необходима возможность масштабирования. При этом крайне важна унификация всех параметров.
  • Вопрос задан
  • 23236 просмотров
Решения вопроса 1
@mithraen
Как только возникает слово «парсинг», в первую очередь стоит вспоминать о Perl (Practical Extraction and Report Language). Для решения этой задачи там есть:

  • модули для работы с HTTP — как низкоуровневые, так и специальные, типа WWW::Mechanize — удобен, если надо написать скрипт, который последовательно выполняет какой-то набор операций (например надо автоматизировать какие-то действия пользователя web-интерфейсе, а API никакого не предусмотрено);
  • модули для асинхронной работы по HTTP (AnyEvent::HTTP) — позволяют написать робота, который без необходимости создавать множество тредов будет выполнять одновременно несколько запросов;
  • регулярные выражения — мощнейший инструмент для парсинга данных, и в perl его использование наиболее удобно (это часть синтаксиса языка);
  • библиотеки для разбора HTML в дерево (например HTML::Parser);


Python хороший скриптовый язык общего назначения, но для задач разбора данных код на Perl будет куда проще.
Ответ написан
Пригласить эксперта
Ответы на вопрос 14
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
В PHP есть XPath, есть библиотеки аля PhpQuery, ну и т.д. Есть возможность запускать одновременно несколько запросов через multi curl. Так что можно организовать это все худо бедно нормально. Все то же самое и даже больше есть в питоне да и в любом другом языке. Так что для этой задачи подойдет любой язык, который вы знаете.
Ответ написан
seriyPS
@seriyPS
У меня половина опыта работы — именно написание пауков и веб-парсеров.
Писал их и на PHP + CURL, потом на голом питоне + треды.
Потом узнал о Scrapy (асинхронный фреймворк для граббинга сайтов на Python) и на нём штук 5 независимых проектов реализовал, в том числе один, где нужно аггрегировать и периодически обновлять информацию с 20 различных форумов. Основная его проблема — он асинхронный, но однопоточный. Так что больше одного ядра им не нагрузить и долгий запрос к БД не сделать. А так очень хороший фреймворк.
Потом несколько пауков делал на Python с помощью Celery.
А совсем недавно переписал довольно сильно нагруженного паука (50-70Мбит/с через списки прокси) с Python + Celery на Erlang и понял, что это ОНО! Мало того, что стал работать в 2-3 раза быстрее, но понял, что для этой задачи что-то более подходящее сложно придумать.
Поясню — у паука на Erlang можно без остановки процесса, например, изменить число потоков, обновить код, перезагрузить конфиги. Можно на ходу отпрофилировать код чтобы узнать, почему скорость упала или что так нагружает CPU. Можно совмещать зеленые потоки, асинхронную работу с сетью и долгие запросы к БД. И всё это фактически из коробки. В конце концов, код получается более логичный.
Ответ написан
Wott
@Wott
ЯП в данной задаче суть третьестепенная задача после разбора html и поиска ключевых элементов.
Поскольку именно последняя задача самая главная, то и ориентироваться надо на нее — обычно кучка регулярок и некий контроллер для отработки вариаций и исключений, поскольку регулярки не идеальный инструмент для этого случая.

Я писал похожую систему для книжного агрегатора на php, но только лишь потому что WP.
Ответ написан
Anonym
@Anonym
Программирую немного )
Какой, по вашему мнению, ЯП лучше всего подходит именно для задачи <любая_задача>?
Тот, который вы знаете лучше всего.
Ответ написан
KEKSOV
@KEKSOV
Что парсер Хабра глючит, может, так получится
$s = file_get_contents( 'yandex.html' );

$tidy = new tidy();
$tidy->parseString( $s, array(
    'output-xml'       => true,
    'clean'            => true,
    'numeric-entities' => true
), 'utf8' );

$tidy->cleanRepair();
$xml = simplexml_load_string( tidy_get_output( $tidy ) );

$adwords = $xml->xpath( '//*[@class="b-adv"]' );
var_dump( $adwords );
exit;

$tads = $xml->xpath( '//*[@id="tads"]' );
var_dump( $tads );
exit;

$a = $xml->xpath( '//a[@href]' );
//var_dump( $a );

array_walk( $a, function( $item ) {
    $href = $item->attributes()->href;
    if ( strpos( $href, 'start=' ) !== false )
        echo $href."\n";
    //var_dump( $attrs );
    //exit;
} ); 
Ответ написан
Guran
@Guran
Для такой задачи пару лет назад использовал Perl с подключением библиотек CPAN'а (в частности HTML::Parser), ибо очень понравилась его работа с regexp'ами. Посмотреть что-то подобное можно тут или тут
Ответ написан
zarincheg
@zarincheg
В PHP есть работа с DOM, XPath. Ну и регулярные выражения разумеется. Что еще надо =)
Ответ написан
KEKSOV
@KEKSOV
Возможно, Вам пригодится вот этот тестовый фрагмент кода, которым я искал блоки диретка на страницах Яндекса.

<source lang="php"> <?php $s = file_get_contents( 'yandex.html' ); $tidy = new tidy(); $tidy->parseString( $s, array( 'output-xml' => true, 'clean' => true, 'numeric-entities' => true ), 'utf8' ); $tidy->cleanRepair(); $xml = simplexml_load_string( tidy_get_output( $tidy ) ); $adwords = $xml->xpath( '//*[class="b-adv"]' ); var_dump( $adwords ); exit; $tads = $xml->xpath( '//*[id="tads"]' ); var_dump( $tads ); exit; $a = $xml->xpath( '//a[href]' ); //var_dump( $a ); array_walk( $a, function( $item ) { $href = $item->attributes()->href; if ( strpos( $href, 'start=' ) !== false ) echo $href."\n"; //var_dump( $attrs ); //exit; } ); ?> </source>
Ответ написан
AterCattus
@AterCattus
Люблю быстрый backend
Можно никуда не уходя с PHP выбрать, что больше нравится.
Ну и подробнее по SHD и phpQ.
Ответ написан
@Inquisitor
Пользовался для парсинга сайтов библиотекой Qt + QtWebKit. Замечательно предоставляет весь DOM, а так же можно вытаскивать текущие размеры и координаты фрэймов и вообще элементов страницы.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Sveak Барнаул
от 50 000 руб.
Девять линий Ульяновск
от 45 000 до 80 000 руб.
САТУРН Санкт-Петербург
от 100 000 до 130 000 руб.
27 июн. 2019, в 01:26
50000 руб./за проект
27 июн. 2019, в 00:27
250000 руб./за проект