Перевод текстов

В срочном порядке ищутся владельцы PROMT Internet Translation Server SDK. Понятное дело, что платной версии.

У меня есть предложение о коммерческом сотрудничестве.

Многопоточный парсер ТИЦ на Perl

В качестве затравки своих Perl навыков предлагаю общественности на рассмотрение Перловый парсер значений ТИЦ.
Код я постарался снабдить большим количеством комментариев, так что разобраться в нем для вас не должно составить проблем.
Также хочу отметить, что данный код я написал не для практического применения, а исключительно в качестве примера многопоточности и ее реализации в Perl.

#!/usr/bin/perl -w
 
# Многопоточный парсер значения ТИЦ
# by ParserPro (http://parse.com.ua | http://parserpro.com)
# 12/01/2008
 
use strict;
use threads;
use threads::shared;
use LWP::Simple;
 
use constant BASE_URL => 'http://bar-navig.yandex.ru/u?ver=2&show=32&url=';   # базовый адрес откуда будем получать значение ТИЦа
use constant MAX_THREADS => 20;                                               # максимальное количество потоков. Можете поставить и больше ;)
 
my $thread_count : shared;                                                    # счетчик потоков
$thread_count=1;
 
# По умолчанию скрипт принимает 2 аргумента:
# - файл с урлами
# - имя файла, в который будут записаны значения ТИЦа
if(@ARGV != 2) {
    die "Usage: tyc.pl <urls_file> <output_file>\n";
}
 
open(URLS,'<'.$ARGV[0]) or die "Не могу открыть файл: $! \n";
my @lines;                  # массив для урлов
while (<URLS>) {
    chop;                   # убрали переводы строки    
    s/^\s+//;               # убрали предшествующие пробелм
    s/\s+$//;               # убрали постшествующие пробелы
    next unless length;     # если после этого длина = 0 перейти к следующей строке
    push @lines, $_;        # запихиваем урлы в большой массив
}
 
open(OUTPUT,'>>'.$ARGV[1]) or die "Не могу создать файл: $!\n";
my @proc;       # массив потоков
my $s = times;  # секундомер
foreach (@lines) {
    while ($thread_count > MAX_THREADS) {}      # пока количество потоков больше MAX_THREADS ждем
    push @proc, threads->create(\&getTYC,$_);   # запускаем поток
    $proc[$#proc]->join();                      # приатачиваем последний запущенный поток к главной программе
}
$s=(times-$s)*60;                               
print "Elapsed time: $s seconds\n";             
 
sub getTYC($) {
    ++$thread_count;     # запустили поток
    my $tycUrl = shift;
    my $url = BASE_URL.$tycUrl;
    my $content = get $url;
    if(defined $content) {
        if ($content =~ /value\=\"(.*?)\"/) {
            if ($1 eq '') {
                print "$tycUrl;!\n";
                print OUTPUT "$tycUrl;!\n";
            } else {
                print "$tycUrl;$1\n";
                print OUTPUT "$tycUrl;$1\n";
            }            
        } else {
            print "$tycUrl;!!\n";
            print OUTPUT "$tycUrl;!!\n";
        }
    } else {
        print "$tycUrl;!!!\n";
        print OUTPUT "$tycUrl;!!!\n";        
    }
    --$thread_count;    # завершили поток
}

У данного кода есть несколько преимуществ:

  • многопоточность
  • простота

и ряд недостатков:

  • использование очень медленной LWP (и как ее подвида LWP::Simple)
  • невозможность работы через прокси (добавить это легко, но мне было лень :) )
  • никакого контроля за адресами и их валидностью - тупо, что получили, то Яндексу и кормим (это добавить еще легче, но мне было еще больше в лень)
  • использование “дурного” метода обработки завершения потока.
    Я хотел использовать, что-то другое, но для него или не подходил мой Перл или работало оно явно не очень хорошо (как в случае с Threads::Queue).

Также скрипт не показал себя сильно производительным. На моем компе проверку 100 URL он произвел за 220 секунду, то есть по 2 секунды на адрес - ОЧЕНЬ МЕДЛЕННО! Также удивил тот факт, что такой примитивный скрипт отгрыз около 5 метров оперативной памяти (наверное ты это имел ввиду, SHAman, когда мы с тобой говорили про потоки). Притом при создании нового потока объем используемой памяти увеличивался. Со временем память высвобождалась. Но само поведение меня потоков меня напрягало.

Так что пробуйте скрипт у себя. Говорите о результатах, делитесь опытом, так сказать. А для себя я еще раз убедился, что PERL POE будет оптимальным решением для моих задач!

Удачи!

Уйти от скриптов?

Постоянно читаю отклики разработчиков высоконагруженных приложений (коими парсеры и грабберы также являются) и просто стараюсь отслеживать что происходит в мире программирования и понемногу начинаю приходить к мысли, что при разработке самых крупных проектов надо отходить от скриптовых языков программирования и обращаться ко всяким там C++, C# и им подобным.

И по этому поводу хочу спросить, что думаю мои подписчики. Кто что пробовал? Какие тесты видели на эту тему? Какие шишки набили? Где многопоточность лучше показала себя? Что успели попробовать? Не молчите - выскажитесь! Поделитесь своим опытом, а другие поделятся с вами. И так все станут хоть на грамм умнее и эффективней!

Спасибо!

Увеличиваем отказоустойчивость парсинга/граббинга

Как я уже отмечал ранее, базы данных в последнее время становятся узким местом для приложений, предназначенных для парсинга, граббинга и сбора информации. Это связано с тем, что сейчас практически любой движок построен на основе четырех десятков таблиц и тучи сложных запросов, а когда на одном хостинге таких движков находится штук 100, то многого просить от БД не приходится, даже с учетом того, что MySQL (а чаще всего хостеры используют именно его) – чертовски быстрая штука при правильной настройке.

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

Например, на одном из хостингов клиента при запуске парсера через 20-30 минут MySQL выдавал «MySQL server has gone away» и после этого вся далее собранная информация уходила в трубу. Также не редкими были проблемы, когда MySQL просто умирал от нагрузок (понятное дело, что не со стороны моих парсеров). Я начал искать решение данной проблемы. Пробовал даже разработать систему отложенного выполнения запросов, ставил таймауты, когда не мог выполнить запрос. В общем, думал я над этой проблемой и пришел к выводу, что проще всего всю информацию записывать в CSV или SQL dump файл, а по окончании парсинга одним запросом выгружать это в БД.

У этого решения есть ряд преимуществ:

  • файловая система намного устойчивей к перегрузкам, чем БД
  • файловая система не уступает по производительности БД (особенно на публичных хостингах)
  • за нагрузки на файловую систему вам не сделают втык админы сервера, в отличии от БД

Но также есть и некоторые недостатки у подобного подхода:

  • сложнее ВИЗУАЛЬНО контролировать процесс сбора информации (это проблема для тех, кто привык смотреть как заполняются его базы данных :))
  • невозможно использовать информацию «на лету» - всегда надо дожидаться завершения парсинга

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

Запуск нового сайта!

Хочу порадовать своих иностранных (западных) клиентов, потому что теперь им не придется звонить по Skype и задавать мне миллион вопросов. Потому что специально для них я запускаю англоязычный сайт ParserPro. В ближайшее время я заполню и его контентом и буду вести блог и на английском языке.

Выходим на интернациональный уровень! :)

Project overflow

Уважаемые потенциальные клиенты!

В связи с огромной загруженностью по проектам на парсинг/граббинг/сбор информации с сегодняшнего дня и по 15.02.2008 я не буду брать дополнительные проекты. Прошу извинить за неудобства.

P.S. На поддержке уже существующих пользователей данное заявление никак не отразится.

Граббер картинок с Яндекс.Картинки

Очень часто при создании сайтов необходимо собрать какую-то галерею тематических картинок или сделать что-нибудь на основе этих тематических картинок. Например, на сайте про футбольную команду всегда будут присутствовать фотографии ее футболистов и их матчей. И при создании подобного сайта возникает задача сбора этих самых фотографий и картинок.

Именно для таких целей я разработал граббер картинок с Яндекс.Картинки.
Возможности граббера:

  • Многопоточная работа (количество потоков выставляется в конфигурационном файле)
  • Возможность ручной установки интервалов между запросами
  • Обработка вложенных картинок (”Еще с …”)
  • Жесткий контроль имен файлов и переименование “на лету”
  • Также в разработке есть очень простой контроллер процесса выполнения. Он вам пригодится, если Яндекс подумает, что вы робот и вам потом не захочется начинать сбор информации сначала. Для самых требовательных клиентов данный контроллер может быть переписан (за отдельную плату) с использование автоматизированной библиотеки контроля процесса выполнения, что поможет вам сэкономить время и силы при рестарте процесса граббинга картинок.

Стоимость данного граббера: 25 $.

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

Удачи!

Новая платформа

В своем предыдущем посте я обещал своим клиентам, что в 2008 году я приступлю к разработке новой платформы и поэтому мне хотелось бы немного о ней рассказать. Думаю, что профи в области парсинга и граббинга информации это будет интересно.

Как вы уже могли видеть, основным языком, которым я пользовался ранее для разработки парсеров и грабберов был PHP. Язык на удивление простой, хорошо документированный и достаточно мощный. На начальных порах, когда в месяц обрабатывалось порядка 500к-800к страниц мне его было достаточно, но с увеличением объемов я начал ощущать, что он не совсем подходит для выполнения подобной работы. Что меня в нем не устроило:

  1. Постоянное “вываливание” Apache по segmentation fault (segfault), что приводило к рестарту Apache и соответственно к перезапуску с САМОГО НАЧАЛА всех скриптов.
    Проблема достаточно дотошная, потому что бороться с segfault очень сложно. И методы борьбы так или иначе влияют на производительность, что в нашем деле, как вы сами понимаете, очень плохо. Возникает данная проблема в результате быстрого нарастания используемой Apache’ем памяти, что понятное дело является следствием “течки” (простите за выражение) PHP.
    Я временно решил данную проблему написав контроллер процесса выполнения, но он увеличивал продолжительность сбора информации в среднем на 8-10%, что мало приятно.
  2. Ограничения Apache.
    Тут есть целый ряд проблем. Сначала Apache не давал мне запускать более 4х пауков, потом некоторые процессы он убивал считая их висячими и т.п…. Данные проблемы удалось решить перейдя на CLI версию PHP, но и с ним пришлось возиться еще больше.

Одним словом, PHP ввел достаточно много ограничений в мою работу, обход которых вводил другие ограничения и так до бесконечности. Я не преуменьшаю достоинств PHP, но для задач парсинга и граббинга информации он не достаточно гибок.

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

Конечно же постоянные рабочие проекты и проекты “под заказ” будут крутиться на PHP, но все новые проекты я буду стараться реализовать на новой платформе. Я надеюсь получить увеличение производительности на 40-70% в результате переноса.

Так что лучше, выше, быстрее!

С Новым Годом

Новый Год с ParserPro - профи по парсингу и граббингу информации

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

Отдельно я хотел бы поздравить своих клиентов, которые доверили свои проекты моим рукам и оставили столь приятные отзывы о моей работе на Weblancer.net и Webmoney.ru. Спасибо вам огромное! Обещаю, что Новый Год мы с вами встретим с новой парсинг-платформой, которая позволит собирать и обрабатывать миллионы записей в сутки.

Поздравляю всех! УДАЧИ!

P.S. До 6ого января я буду в отпуске, поэтому прошу всех моих великолепных заказчиков немного потерпеть. Когда я вернусь с новыми силами я удивлю вас своей производительностью! ;)

Посещаемость

Как-то странно упала посещаемость моего сайта. Притом упала в разы. Видно Гугл и Яндекс наказывают меня за то, что я с них ссылки собирал :)))