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

понедельник, 17 ноября 2008 г.

Парсинг ников пользователей для форумов

Напарсить где-нибудь ников пользователей еще проще, чем напарсить аватаров. Для этого достаточно зайти на форум или сайт, на котором есть поиск пользователей. Желательно, чтобы там был выбор по полу. Вот, например, на сайте НайтПати зарегистрированы тысячи ночных тусовщиков из разных городов России. Идем на страницу поиска юзеров http://msk.nightparty.ru/users.php.

Изучаем get-запрос скрипта поиска, смотрим, что передается, смотрим идентификатор России и города Москвы. Смотрим идентификатор пола. Смотрим, как организована пагинация. В принципе, больше ничего и не надо.

Потом составляем какое-нибудь регулярное выражение для нахождения ников на конкретном сайте.

Рисуем формочку:
Кроме двух кнопок больше ничего и не надо. Вторая кнопка тоже исключительно для самых нетерпеливых, которым лень подождать, когда появится сообщение "Все сделано".

Привожу полностью рабочий код всего юнита целиком:

unit UserFinderU;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, Urlmon;

const
GirlUserListFileName = 'g_users.txt';
BoyUserListFileName = 'b_users.txt';
GirlSearchURL = 'http://msk.nightparty.ru/users.php?action=dosearch&country_id=103&city_id=1043&user_sex=2&page=[PageNum]';
BoySearchURL = 'http://msk.nightparty.ru/users.php?action=dosearch&country_id=103&city_id=1043&user_sex=1&page=[PageNum]';
FindUserRegExp = 'style="padding-left:8px;"><a href="http://(?:.*?)\.at\.nightparty\.ru/"><b>(.*?)</b>';

function DownloadFile(SourceFile, DestFile: string): Boolean;

type
TForm1 = class(TForm)
btnStart: TButton;
btnStop: TButton;
cbGender: TComboBox;
Label1: TLabel;
procedure btnStartClick(Sender: TObject);
procedure btnStopClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
vStop : boolean;

implementation

uses
VBScript_RegExp_55_TLB;

{$R *.dfm}

procedure TForm1.btnStartClick(Sender: TObject);
var
i, j, t,
PageNum : integer;
FName,
SearchURL,
LinkStr,
sFileName,
currBody
: string;
NextPage : boolean;
SLBody : TStringList;
RE : TRegExp;
mc : MatchCollection;
sm : SubMatches;
mm : Match;
f : TextFile;
UsersList : TStringList;
begin
if cbGender.ItemIndex = 0 then
begin
FName := GirlUserListFileName;
SearchURL := GirlSearchURL;
end;
if cbGender.ItemIndex = 1 then
begin
FName := BoyUserListFileName;
SearchURL := BoySearchURL;
end;

PageNum := 0;
NextPage := true;
UsersList := TStringList.Create;

//======================

vStop := false;
while NextPage and not vStop do
begin
LinkStr := StringReplace(SearchURL,'[PageNum]',IntToStr(PageNum),[rfIgnoreCase]);
try
SLBody:=TStringList.Create;
RE := TRegExp.Create(Self);

sFileName:=ExtractFilePath(Application.ExeName) + 'cache.txt';
currBody:='';
if DownloadFile(LinkStr,sFileName) then
SLBody.LoadFromFile(sFileName);
currBody:=SLBody.Text;
DeleteFile(sFileName);

// ищутся пользователи
RE.Pattern := FindUserRegExp;
RE.Global := true;
RE.IgnoreCase := true;
RE.Multiline := true;

mc := RE.Execute(currBody) as MatchCollection;
for j := 0 to mc.Count-1 do
begin
mm := mc[j] as Match;
sm := mm.SubMatches as SubMatches;
UsersList.Add(sm.Item[0]);
end;
if mc.Count = 0 then NextPage := false;

finally
SLBody.Free;
mm := nil;
sm := nil;
mc := nil;
RE.Free;
end;
inc(PageNum);

for t := 0 to 10 do
begin
Sleep(100);
Application.ProcessMessages;
end;
end;

UsersList.SaveToFile(ExtractFilePath(Application.ExeName)+FName);

UsersList.Clear;
UsersList.Free;
ShowMessage('Все сделано.');
end;

procedure TForm1.btnStopClick(Sender: TObject);
begin
vStop := true;
end;

function DownloadFile(SourceFile, DestFile: string): Boolean;
begin
try
Result := UrlDownloadToFile(nil, PChar(SourceFile), PChar(DestFile), 0,
nil) = 0;
except
Result := False;
end;
end;

end.


Далее запускаем программу и занимаемся другими делами (например, продолжаем программировать свой другой-супер-мега-проект-который-принесет-кучу-БАБЛА %D ). Паузу между запросами я поставила по секунде, так что минут 15 уйдет на полное сканирование всех страниц с пользователями одного пола. Итак, через некоторое время мы получим файлики с мужскими и женскими никами, тех и других тысяч по 12. Можем использовать их для своих чистых дел). Чтобы лишний раз не грузить всуе упомянутый мной сайт, можете взять готовые списки у меня. Обращайтесь на почту, указанную в профиле.

=====

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

=====

Если вы пришли на блог с поисковика в надежде скачать базу ников, то вам нужно в другое место :)

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



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

  1. Замечательный блог. Маше респект! Я вот пытаюсь написать бота для браузерной игры, тут почерпнул много полезного =)
    Товарищу, который собирается писать в 10 000 блогов ИМХО лучше делать это через XML-RPC, это проще, быстрее и решает проблему совместимости между разными движками блогов.
    Маша, скажи пожалуйста, какую версию делфей ты используешь, есть ли смысл работать с делфи для .NET?
    С нетерпением жду рассказа о многопоточности в делфи для Win32 =)

    ОтветитьУдалить
  2. Совсем недавно сам парсил один форум собирая ники. Поиск не делал, ибо на форуме была страничка http://.....ru/memberlist.php?do=getall&order=asc&sort=username&page=

    Т.е. было достаточно добавлять в конец этого адреса номер страниц (всего кажется было чуть больше 700) и вытащить регэкспом имена.

    Правда гарбилку-ников писал просто ради интереса. Большого толка от собранного не получил :) А вам зачем нужно столько ников?

    Думаю гораздо интереснее было бы не просто ники собирать, а ещё и содержание анкет "О себе". Но до этого руки пока не дошли. Но в качестве возможного "источника" хочу рассмотреть сайты знакомств с мамбы.

    ОтветитьУдалить
  3. galen, спасибо за отзыв! А какого рода браузерная игра?
    Я работаю с 7-ой версией делфи. С дотнетом вообще не сталкивалась, если честно...

    ОтветитьУдалить
  4. Vimruler, ну мне не все ники понадобились, а только их часть. Я их использую в своей программе по полуавтоматическому наполнению форумов) Первоначально на свежем форуме "регистрируются" пользователи-боты и форум заполняется информацией, напарсенной с подобных тематических форумов и немного синонимизированной. Анкеты у ботов я заполняю по минимуму: ник, аватар, случайный город и случайная подпись (или отсутствие подписи). Этого вполне достаточно.

    ОтветитьУдалить
  5. >> А какого рода браузерная игра?
    Игра типа бойцовского клуба combats.ru, сейчас таких полно =)

    в дотнете мне нравится приемущества, которые даёт манагер памяти, но переучиваться на c# не хочется.

    ОтветитьУдалить
  6. Спасибо хозяйке за замечательные материалы, занес сайт в избранное.
    В PHP не особо силен, а гугел помогать не хочет. Что означает регулярка .*?
    Предполагаю, что любые символы, сколько угодно раз, но не меньше одного?

    ОтветитьУдалить
  7. Drake, само по себе выражение .* обозначает любое количество любых символов, а знак вопроса после этого квантификатора ограничивает его "жадность". Без знака вопроса все квантификаторы захватывают как можно большее количество повторений. Я бы привела пример, но в комментарии код не получается правильно оформить)) Можешь поискать в гугле что-нибудь типа "ограничение жадности квантификаторов" — станет понятно)

    ОтветитьУдалить
  8. Огромное спасибо- разобрался. Добавил еще и ссылочку на вас.

    ОтветитьУдалить
  9. спасибо, а можно чтобы еще инфу о: дата происхождения, дата регистрации, ну и все остальное фуфло что там заполняют или не заполняют.

    так неуднобно в текстовый файл все это копировать, муторно. (можно конечно сохранить HTML но с ним неудобно.

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

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

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

Поделиться