Поиск по блогу

среда, 8 октября 2008 г.

Парсинг выдачи поисковиков. Определение позиции сайта. Часть II

В предыдущей части инструкции по созданию парсинга выдачи поисковиков я описала начало процесса создания утилиты. Идем дальше.

Остановлюсь на содержимом INI-файла. В секции MAIN разместим ссылку на сайт, который чаще всего проверяем и ключевые слова через разделитель. В секции SITE01 разместим информацию для парсинга Яндекса. Регулярное выражение для парсинга выдачи Яндекса составила, не особо заморачиваясь. Но оно недолговечно, может измениться, это надо помнить.


[MAIN]

DefSite=http://parsing-and-i.blogspot.com/
DefWords=парсинг|парсер на Delphi

[SITE01]

Name=Yandex.ru
NextPageTmpl=http://yandex.ru/yandsearch?p=[NumPage]&text=[Word]&numdoc=50
LinkRegExp=<a tabindex="\d{1,}".*href="(.*)" target="_blank">(.*)</a>(?:\x0D\x0A|\n|)</div>


Вместо [NumPage] при реализации алгоритма будем подставлять номер страницы в выдаче, вместо [Word] — поисковый запрос.

Алгоритм будет следующий: по очереди проходимся по списку поисковых систем, для каждой системы рассматриваем список ключевиков. Загружаем страницу результатов выдачи по запросу, выделяем все позиции сайтов, проверяем, есть ли сайт в выдаче. Если есть — смотрим место и переходим к следующему запросу. Если нет — переходим на следующую страницу (не заходя за рамки указанного для просмотра количества позиций). И так все операции в цикле. Результат выводим в грид.

Я намеренно не привела код на данном этапе. Алгоритм работает, все парсится. Оттестировав программу на Яндексе, я захотела продолжить вечеринку с Гуглем. Но...

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

[SITE02]

Name=Google.ru
NextPageTmpl=http://www.google.com/search?q=[Word]&num=100&hl=ru&start=[NumPage]


Тут обнаружилось, что в Яндексе надо указать просто номер страницы, начиная с нуля, а в гугле надо указать номер позиции, с которой начинается отсчет (нумерация с нуля, как у всех программистов :) ). Похоже, придется делать заплату. Ввожу KoeffForPages. Внутри алгоритма буду умножать номер страницы на этот коэффициент. Для Яндекса он будет равен единице, а для Гугля — количеству выводимых позиций на странице.

В результате INI-файл содержит:
[MAIN]

DefSite=http://parsing-and-i.blogspot.com/
DefWords=парсинг|парсер на Delphi

[SITE01]

Name=Yandex.ru
NextPageTmpl=http://yandex.ru/yandsearch?p=[NumPage]&text=[Word]&numdoc=50
KoeffForPages=1
LinkRegExp=<a tabindex="\d{1,}".*href="(.*)" target="_blank">(.*)</a>(?:\x0D\x0A|\n|)</div>

[SITE02]

Name=Google.ru
NextPageTmpl=http://www.google.com/search?q=[Word]&num=100&hl=ru&start=[NumPage]
KoeffForPages=100
LinkRegExp=<h3 class=r><a href="(.*?)"


А класс в программе выглядит:
  TSearcher  = class
Name,
NextPageTmpl,
LinkRegExp : string;
KoeffForPages : integer;
end;


И так далее. Процесс программирования — вещь сама по себе очень интересная. Остальные поисковые системы я разбирать не буду.

После реализации алгоритма запускаю прогу:
парсинг позиций в поисковиках

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

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

Скачать: исходник парсера (6 кб), скомпиленный парсер (1,12 Мб).

Статьи схожей тематики:



13 комментариев:

  1. А как нить, типа выложить готовый ini файл, с готовыми настройками можно. И если уж пишите про ini файл, может имеет смысл указать его имя, а то я его создал, а ваша программа ни фига не видит.

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

    Ссылки на скачивание внизу статьи есть и вроде работают. Ini-файл должен лежать в одной директории с программой.

    ОтветитьУдалить
  3. А мне понравилось. И пофик, что исходник открылся с ошибками (не нашел компонент грида и ещё что-то там). Не в этом дело. Главно, что можно просмотреть исходник и самому понять как должен называться файл и где он должен лежать) Думаю, что стоит продолжить эту тему :) Естественно с сохранением всех авторских прав на некоторые из функций

    ОтветитьУдалить
  4. да и ещё 1 момент. Если вдруг кто-то захочет воспользоваться исходниками. Регулярка для Яндекс срабатывает не всегда, т.е. она работает нормально но некоторые позиции не вытаскивает. Проблема кроется вот тута:
    (?:\x0D\x0A|\n|) /div (див в треугольных скобках, с ними не дает коммент кинуть)
    Если убрать эту подстроку, то вроде ьы всё нормально проходит. Вполне возможно, что чего-то Яндекс сменил в своей выдаче

    ОтветитьУдалить
  5. Да, возможно, что Яндекс что-то поменял, я давно не проверяла)

    ОтветитьУдалить
  6. Маша, здравствуйте!
    Вопрос к Вам по парсингу того же Гугла, но картинок. Странная вещь - написан кусок кода, который спокойно собирает картинки. В первый раз. Затем не выключая программы меняешь запрос - и все, гугл пишет didn't match any documents. Запускаешь программу заново - все опять находится. При этом idhttp cоздается динамически и даже никаких куки не хранит. Нужен хелп!
    Заранее спасибо,
    _dk_

    ОтветитьУдалить
  7. _dk_, к сожалению, я не экстрасенс, по одному описанию, без кода, не могу вам помочь решить проблему :)

    ОтветитьУдалить
  8. Сорри, не прикрепился(
    procedure google;
    var s: TStringstream; e,ssize,slink: string; jtmp,z:Byte; idhttp12:TIdHTTP;

    begin
    s:=TStringstream.Create('');
    e:='';
    goj:=0;
    idhttp12:=tidhttp.Create(nil);
    for jtmp:=1 to 21 do begin
    go[jtmp].url:='';
    go[jtmp].w:=0;
    go[jtmp].h:=0;
    end;
    slink:='http://www.google.com/images?um=1&hl=en&newwindow=1&tbs=isch%3A1&sa=1&q='+sxnamepl+'+'+sxalbumpl+'&aq=f&aqi=&aql=&oq=&gs_rfai=';
    repeat
    try begin
    IdHTTP12.Disconnect;
    IdHTTP12.AllowCookies:=false;
    idHTTP12.Response.KeepAlive:=true;
    IdHTTP12.request.useragent:=useragents[Random(8)+1];IdHTTP12.Disconnect;
    IdHTTP12.Get(slink,s);
    end;
    finally
    idhttp12.Free;
    end;
    e:=s.DataString;
    if e<>'' then Break;
    until False;
    repeat
    if Pos('["/imgres?imgurl\x3d',e)=0 then begin
    break;
    end;
    Delete(e,1,Pos('["/imgres?imgurl\x3d',e)+length('["/imgres?imgurl\x3d')-1);
    inc(goj);
    go[goj].url:=Copy(e,1,Pos('\',e)-1);
    for jtmp:=1 to 18 do begin
    Delete(e,1,pos('"',e));
    end;
    ssize:=Copy(e,1,Pos('×',e)-2);
    z:=0;
    while z0 then begin
    delete(ssize,pos(' ',ssize),1);
    dec(z);
    end;
    if pos(#$A,ssize)>0 then begin
    delete(ssize,pos(#$A,ssize),1);
    dec(z);
    end;
    if pos(#$D,ssize)>0 then begin
    delete(ssize,pos(#$D,ssize),1);
    dec(z);
    end;
    end;
    go[goj].w:=StrToInt(ssize);
    ssize:=Copy(e,Pos('×',e)+8, pos('-',e)-pos('×',e)-8);
    z:=0;
    while z0 then begin
    delete(ssize,pos(' ',ssize),1);
    dec(z);
    end;
    if pos(#$A,ssize)>0 then begin
    delete(ssize,pos(#$A,ssize),1);
    dec(z);
    end;
    if pos(#$D,ssize)>0 then begin
    delete(ssize,pos(#$D,ssize),1);
    dec(z);
    end;
    end;
    go[goj].h:=StrToInt(ssize);
    if (go[goj].h>picparam) or (go[goj].w>picparam) then
    Dec(goj);
    until False;
    s.free;
    end;

    В первый раз все отлично находится, потом на вход подаются другие sxname и sxalbum, и Pos('["/imgres?imgurl\x3d',e)=0 и гугл выдает страницу с надписью did not match any documents, хотя на деле там все есть. Где мог какой хвост остаться? Или еще как?

    Заранее спасибо,
    _dk_

    ОтветитьУдалить
  9. Ой, как много всего написано :) Мда... я сейчас на работе, мне пока некогда разбираться в этом коде. Как будет свободное время — посмотрю. Если, конечно, до этого времени вы сами не найдете, в чем там трабла.

    ОтветитьУдалить
  10. смену юзерагентов он не любит почему-то..
    все заработало, в любом случае, спасибо)

    _dk_

    ОтветитьУдалить
  11. Мария и все читатели этого блога!!!)))
    Пожалуйста,помогите написать похожий парсер для поисковиков на Objective-C !!! очень нужен!)))

    ОтветитьУдалить
  12. Олег, думаю, ничего сложного... Но вряд ли кто прямо тут вам выдаст готовое решение) Если умеете программировать — программируйте... или можно на фрилансе поискать исполнителя)

    ОтветитьУдалить
  13. Если когото интересует могу дать или выложить исходник парсера google.com на C++.
    Мой ICQ 553-189-009

    ОтветитьУдалить

Комментарии модерируются, вопросы не по теме удаляются, троллинг тоже.

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

Поделиться