Всем привет. Понадобилось с одного форума спарсить ники с мемберлиста. В браузере можно авторизироваться через сайт, и попасть на форум уже залогиненым. Тоже самое пытался сделать в программе, на сайте я логинюсь нормально, а вот при попытке проги получить код списка пользователей, я попадаю на страницу уже не авторизированным. Прошу подсказать как можно исправить ситуацию. А то вручную копипастить 265к логинов как-то обломно ) Code: procedure TForm1.btn1Click(Sender: TObject); var Http : TidHttp; CM : TidCookieManager; Data : TStringList; StrPage, UserID, UserName : String; i : integer; s: string; begin try Http := TIdHTTP.Create(Self); Data := TStringList.Create; CM := TidCookieManager.Create(Http); Http.AllowCookies := true; Http.CookieManager := CM; Http.HandleRedirects := true; Http.Request.Host:='www.gamescampus.com'; Http.Request.UserAgent:='Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; MRSPUTNIK 2, 4, 0, 270; MRA 5.8 (build 4133); SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)'; Http.Request.Accept:='text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'; Http.Request.AcceptLanguage:='ru-RU'; Http.Request.AcceptCharSet:='windows-1251,utf-8;q=0.7,*;q=0.7'; Http.Request.Referer:='http://scarletlegacy.gamescampus.com/'; Data.Add('uid=deleted'); Data.Add('pwd=deleted'); Data.Add('x=37'); Data.Add('y=17'); StrPage := Http.Post('http://www.gamescampus.com/account/login_exec.asp?rtnurl=http://scarletlegacy.gamescampus.com/', Data); s:= idhtp1.get ('http://forum.gamescampus.com/memberlist.php') ; mmo2.Lines.Text:= s finally Data.Free; CM.Free; Http.Free; end; if Pos('Hello, <a href="http://www.gamescampus.com/account/modify_view.asp?gamescampus=scarletlegacy" target="_top">'+Edt1.Text,StrPage) <> 0 then ShowMessage('Зашли') else ShowMessage('Это fail =('); Mmo1.Lines.Text := StrPage; end; Можно конечно напрямую через форум логиниться, но у меня там не получается авторизация из-за сесии (sid). Просто в браузере проблем не возникает при переходе с сайта на форум, а в проге возникает...почему ?
s:= idhtp1.get ('http://forum.gamescampus.com/memberlist.php') ; Ты выполняешь эту строчку, а потом определяешь(как я понял) удачность авторизации. Если не разберешься, завтра утром помогу. EDIT: у тебя могут быть траблы с CookieManager'ом, если это Delphi 7.
Я уже по всякому пробовал, и на другой батон вешал, и после проверки делал, и так и сяк.. уже всё перепробовал. Разобраться так и не смог. Делфи да, семерка. На семерке я раньше уже писал подобные вещи, всё было без проблем. Правда это было давно, и сборка была другая.
Есть какие-то мануалы по апдейту инди ? А то почти все ссылки мертвые, многие ссылались на квенди, но сайт мертвый. upd. Вроде нашел.
Актуальная версия Indy находится только в SVN репозитории разработчиков, значит нам понадобится клиент SVN под Windows. Наиболее популярным клиентом является tortoisesvn, который можно скачать на сайте разработчика. Затем устанавливаем его. Для простоты можем в настройках (после установки) указать язык интерфейса русский. Перегружаемся. Теперь выберем место, где у нас будет располагаться папка с нашими актуальными компонентами, щелкаем правой клавишей мыши на свободном месте в проводнике и выбираем пункт TortoiseSVN->Экспорт… В появившемся окне в поле URL Хранилища впишите адрес репозитория Indy «https://svn.atozed.com:444/svn/Indy10/» в поле «Папка экспорта» выберите папку куда экспортировать компоненты. Затем нажмите ОК, у вас спросят логин с паролем в поле имя пользователя впишите «Indy-Public-RO», пароль указывать не нужно. Теперь дождитесь окончания операции. Запустите Delphi , выберите в меню «Component»->»Install Packages». В появившемся списке снимите галки с всех пакетов Indy. И затем удалите все пакеты Indy в этом же списке, воспользовавшись кнопкой remove. Затем откройте окно настроек среды: меню «tools->options->Library Win32″ и удалите из строки Library path пути к исходным кодам Indy. Затем добавьте в Library path 3 пути: 1. «<папка, куда вы экспортировали репозиторий Indy>\branches\Tiburon\Lib\System« 2. «<папка, куда вы экспортировали репозиторий Indy>\branches\Tiburon\Lib\Core« 3. «<папка, куда вы экспортировали репозиторий Indy>\branches\Tiburon\Lib\Protocols« Закройте Delphi. Далее найдите в папке, где у вас установлена Delphi исходные коды Indy. Обычно они располагаются в папке «<папка с Delphi>/sources/Indy» и удалите эту папку. Далее в папке Lib, которая располагается по адресу «<папка установки Delphi>/lib» удалите все файлы Indy (поиск по вхождению «Indy» вам в этом поможет).Теперь запустите Delphi, и откройте пакет «IndySystemX0.dpk» (где X – это ваша версия Delphi), который располагается по следующему адресу: «<папка, куда вы экспортировали репозиторий Indy>\branches\Tiburon\Lib\System» и скомпилируйте его. Далее откройте пакет «IndyCoreX0.dpk» (где X- это ваша версия Delphi) из папки «<папка, куда вы экспортировали репозиторий Indy>\branches\Tiburon\Lib\Core» и скомпилируйте его. Теперь откройте и скомпилируйте пакет «IndyProtocolsX0.dpk» (где X – это ваша версия Delphi) , который располагается в папке «<папка, куда вы экспортировали репозиторий Indy>\branches\Tiburon\Lib\Protocols«.Далее откройте пакет «dclIndyCoreX0.dpk», который располагается в папке «<папка, куда вы экспортировали репозиторий Indy>\branches\Tiburon\Lib\Core» и установите его, также установите пакет «dclIndyProtocolsX0.dpk» из папки «<папка, куда вы экспортировали репозиторий Indy>\branches\Tiburon\Lib\Protocols». Вот и все, поздравляю, теперь у вас установлена актуальная версия Indy.
Мануал видимо устаревший, ибо нужных папок или ещё чего-то нету, или находятся в другом месте. Так и не смог обновиться. Скачал сборку делфи уже с 10-ым инди, установил и переустановил раз 20, при попытке юзать в ней инди и закомпилить проект, ругает на разные версии indy. Хотя все старые компоненты я чистил согласно инструкция.. беда какая-то. Впорос такой, а точно дело в инди ? Может я зря уже 4-ый час мучаюсь ? Может всё таки в коде что-то ?
из этого мануала слово Branches\Tributron выкинуть из путей нужно и все ок. внимательно поищи и удали в папке windows\system файлы по маске *indy*.* их старичок закидывает туда.
Я всё это проделывал уже. Я полносью удалял делфи, и все файлы с разрешением dcp, dcu и ещё каким-то разрешением. То есть полностью чистил комп от всего что может бытьс вязано с делфи. Ставил сборку с 10 инди, и в итоге он ругался на версии. System32 тоже чистил... итог один. Пойду уже хз в какой раз заного пробовать. Блин бесит уже -_- [Fatal Error] Unit1.pas(8): Unit IdHTTP was compiled with a different version of IdException.EIdException [Fatal Error] Unit1.pas(7): Unit IdCookieManager was compiled with a different version of IdBaseComponent.TIdBaseComponent Как пофиксить ? Удалял уже всё что только можно было удалить, развее что реестр не чистил. Может всё же пропустил что-то ? Чистил system32 , сносил целиком делфи со всеми папками, что ещё можно сделать ? Ыыы, ребут компа не поможет ?) А то был как-то случай..
не знаю, никогда такой ошибки не видел... а ты запускал файлик fullD7.bat? удалил старую папку D7? пути все указаны?
Если я установлю делфи без инди, и потом буду по мануалу устанавливать, нормально всё встанет, или чего-то не хватать будет ?
Фуууухх с 10 утра обновлял этот инди... Раньше бы этот гайдик... Спасибо И то только с 3 попытки всё встало ровно. Но собственно с обновлением Indy проблема описанная в первом посте так и не решилась. Есть у кого какие соображения ? Логинится на сайт нормально, но при переходе на форум логин теряется.
Вот код, авторизация работает. Но, из за глючности TIdCookieManager со старого Indy(Лень щас обновлять) не получается зайти именно на форум, с новой версии в теории должно работать, даже если где то косяки(ведь сам парсинг не отладил) - думаю не сложно исправить. Code: Var Users : Record Names : array of String; Count : Cardinal; end; type TStringArray = array of String; function Parse(Login, Pass : String) : Boolean; Const ForumUrl = 'http://forum.gamescampus.com/forum.php'; RealignCount = 1000; function PosEx(Const Start : Cardinal; Const V : String; Const Text : PString) : Cardinal; Var i : Cardinal; j : Integer; Begin j := 1; for i := Start to Length(Text^) do if V[j] = Text^[i] then Begin if j >= Length(V) then Begin Result := i - j + 1; Exit; end; Inc(j); end else Begin j := 1; if V[j] = Text^[i] then Inc(j); end; Result := 0; end; function ParseString(Const Start : Cardinal; Const S, E : String; Const Text : PString) : String; Var i, j : Cardinal; Begin Result := ''; i := PosEx(Start, S, Text); if i = 0 then Exit; j := PosEx(i + Length(S), E, Text); if j = 0 then Exit; Result := Copy(Text^, i+Length(S), j - Length(S) + 1); end; procedure MultiParseString(Const S, E : String; Const Text : PString; Var sa : TStringArray); Var i, j : Cardinal; Begin i := 1; SetLength(sa, 0); while i <= Length(Text^) do Begin i := PosEx(i, S, Text); if i = 0 then Exit; j := PosEx(i + Length(S), E, Text); if j = 0 then Exit; SetLength(sa, High(sa)+2); sa[High(sa)] := Copy(Text^, i+Length(S), j - (Length(S) + 1)); i := j + Length(E); end; end; procedure SafeAddMember(Value : String); Begin if Users.Count > High(Users.Names) then SetLength(Users.Names, Users.Count + RealignCount); Users.Names[Users.Count] := Value; Inc(Users.Count); end; Var i, Page : Integer; done : Boolean; sa : TStringArray; http : TIdHTTP; post : TStringList; html, forumHash : String; Cookies : TIdCookieManager; Begin Randomize; Result := false; post := TStringList.Create; http := TIdHTTP.Create(nil); Cookies := TIdCookieManager.Create(http); http.CookieManager := Cookies; try {Set Headers} with http.Request do Begin UserAgent := 'Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0'; Accept := '*/*'; AcceptLanguage := 'ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3'; AcceptCharset := 'windows-1251,utf-8;q=0.7,*;q=0.7'; Connection := 'close'; Referer := ''; end; {Auth request} with post do Begin Clear; Add('rtnurl=' + ForumUrl); Add('saveid=Y'); Add('uid=' + Login); Add('pwd=' + Pass); Add('Sign+In.x=' + IntToStr(Random(84))); Add('Sign+In.y=' + IntToStr(Random(27))); end; try http.Post('http://www.gamescampus.com/account/meta/user_signin.asp', Post); except on e1 : EIdProtocolReplyError do Result := (http.Response.ResponseCode = 302) and (http.Response.Location = ForumUrl); on e2 : Exception do Exit; end; if not Result then {Åñëè íå àâòîðèçîâàëèñü} Exit; {Get forum page } html := ''; try html := http.Get(ForumUrl); except Exit; end; forumHash := ''; with Cookies.CookieCollection do for i := 0 to Count - 1 do if Items[i].CookieName = 'phpbb3_ddsge_sid' then Begin forumHash := Items[i].Value; Break; end; if Length(forumHash) = 0 then Exit; {Parse memberlist page} {Pre init} Page := 0; Users.Count := 0; SetLength(Users.Names, 0); repeat try html := http.Get('http://forum.gamescampus.com/memberlist.php?sid=' + forumHash + '&start=' + IntToStr(Page)); except end; MultiParseString('<td class="genmed row" align="left"><a href="', '</td>', @html, sa); done := true; for i := 0 to High(sa) do Begin html := ParseString(1, '">', '</a>', @sa[i]); if Length(html) <> 0 then Begin SafeAddMember(html); done := false; end; end; Inc(Page, 50); until done; finally http.Free; post.Free; end; SetLength(Users.Names, Users.Count); Result := true; end; Если все верно - вернет true и в массиве Users.Names будут все логины, иначе - какая то ошибка.
Jingo Bo Большое спасибо за труды, но у меня чего-то не получается весь этот шедевр прикрутить к себе, если не сложно, можешь исходник скинуть с компилящимся проектом ? Буду оч признателен. А то код на данном этапе для меня слишком сложен )) Code: Build [Warning] Unit1.pas(75): Variable 'Http' might not have been initialized [Warning] Unit1.pas(73): Variable 'Data' might not have been initialized [Warning] Unit1.pas(74): Variable 'CM' might not have been initialized [Hint] Unit1.pas(47): Variable 'UserID' is declared but never used in 'TForm1.btn1Click' [Hint] Unit1.pas(47): Variable 'UserName' is declared but never used in 'TForm1.btn1Click' [Hint] Unit1.pas(48): Variable 'i' is declared but never used in 'TForm1.btn1Click' [Warning] Unit1.pas(112): Combining signed and unsigned types - widened both operands [Warning] Unit1.pas(131): Combining signed and unsigned types - widened both operands [Warning] Unit1.pas(134): Combining signed and unsigned types - widened both operands [Warning] Unit1.pas(134): Combining signed and unsigned types - widened both operands [Warning] Unit1.pas(141): Comparing signed and unsigned types - widened both operands [Warning] Unit1.pas(146): Combining signed and unsigned types - widened both operands [Warning] Unit1.pas(150): Combining signed and unsigned types - widened both operands [Warning] Unit1.pas(150): Combining signed and unsigned types - widened both operands [Warning] Unit1.pas(151): Combining signed and unsigned types - widened both operands [Warning] Unit1.pas(156): Comparing signed and unsigned types - widened both operands [Error] Unit1.pas(199): Undeclared identifier: 'EIdProtocolReplyError' [Error] Unit1.pas(216): Undeclared identifier: 'CookieName' [Error] Unit1.pas(218): Undeclared identifier: 'Value' [Warning] Unit1.pas(232): Unsafe code '@ operator' [Warning] Unit1.pas(236): Unsafe code '@ operator' [Error] Unit1.pas(255): ';' expected but '.' found [Error] Unit1.pas(257): Declaration expected but end of file found [Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'
Седня пробовал в Delphi XE, так там другой баг с CookieManager'ом, видимо без правки модулей не выйдет, или же самому писать менеджер куков.
В общем я пришел к выводу что лучше уже тогда сразу на форуме попытаться залогиниться. Будет несколько сложнее, ну зато может тогда всё заработает. З.Ы. Проектик в виде исходника всё равно бы с удовольсвтием посмотрел бы, тот что ты выше выклаывал )
Первый совет: Установи себе RAD 2010 ++ Второй совет: Выкинь CookieManager из проекта Третий совет: HTTP.Request.RawHeaders.Text \ HTTP.Response.RawHeaders.Text из response вытаскивай Set-Cookie: ....... и HTTP.Request.RawHeaders.AddString('Cookie: ' + вытащенные кукис из response); При этом всём если у тебя HTTP.AlloweCookie := True; То ставь её в False и все куки даваемые тебе сайтом забирай и вставляй так как я показал...Удачи P.S. Если, что-то пойдет не так, то организуй все заголовки HTTP.Request в точности как в твоём браузере!
Вот архив с полным проектом, парсит, тут используется свой простой парсер куков. Проще было бы Indy поправить, но ставить ее обновленную сложно, так что такие извороты, менеджер куков не учитывает path'ы, но для данной задачи работает. http://zalil.ru/31616868
Блин, большое спасибо тебе за труды, даже зарегился на том сайте )) Сейчас буду пытаться разобраться с твоим кодом. А то проект скомпилировал, нажал заветную кнопочку, и уже 10 минут жду пока прога отвиснет. Я так понимаю в данный момент она в мемо грузит все ники. Надо бы какое-то ограничение ей сделать и по кускам выдергивать ))) UPD. Не, вроде поправил для теста чтобы с 5280 страницы начинал (всего 5283) , жму загрузить и всё равно виснит на оч. долго так ничего и не собрав.... Че то ну ни как мне не везет с этим парсером Буду разбираться что не так. Кстати, первый раз че то не придал значения этому - При открытии проекта вылетает еррор Может в этом дело ? оО Точнее даже не может, а видимо в этом и есть дело )