Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 10.12.2013, 18:01
Taemin Taemin вне форума
Прохожий
 
Регистрация: 07.02.2012
Сообщения: 45
Репутация: 10
По умолчанию Простой парсинг

Здравствуйте, хочу научиться для себя парсить сайты с помощью Synapse. В качестве примера взял сайт pikabu. Снифером внимательно отследил данные, отправил их методом POST, залогинелся, но вот как уже под своим логином перейти на другую страницу этого ресурса и выгрузить html код страницы?

Попробовал реализовать следующим образом:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, httpsend, ssl_openssl, StdCtrls;

type
  TForm1 = class(TForm)
    btn1: TButton;
    mmo1: TMemo;
    edt1: TEdit;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function FoundLocationStrNum(Headers: TStringlist): integer;
var
  FoundStrPos, i: integer;
begin
  Result := -1;
  for i := 0 to Headers.Count do
  begin
    FoundStrPos := Pos('Location: ', Headers.Strings[i]);
    if FoundStrPos > 0 then
    begin
      Result := i;
      exit;
    end;
  end;
end;

function GetHTTPStr(http: THTTPSend): string;
var
  BodyStream: TStringStream;
  BodyS: TStringList;
begin
  try
    BodyS := TStringList.Create;
    BodyStream := TStringStream.Create(result);
    begin
      BodyS.LoadFromStream(http.Document);
      result := BodyS.Text;
    end;
  finally
    BodyStream.Free;
    BodyS.Free;
  end;
  http.Document.Seek(0, soFromBeginning);
end;

procedure TForm1.btn1Click(Sender: TObject);
var
      httpsend: THTTPSend;
      stream: TStringStream;
      n: integer;
      NewURL, result: string;
      Res: boolean;

begin
httpsend:= THTTPSend.Create;
stream := TStringStream.Create('');
stream.WriteString('mode=login&username=***&password=***&remember=1');
Application.ProcessMessages;
httpsend.MimeType := 'application/x-www-form-urlencoded';
httpsend.Document.LoadFromStream(stream);
Res := httpsend.HTTPMethod('post', 'http://pikabu.ru/ajax/ajax_login.php');
Application.ProcessMessages;

    case httpsend.ResultCode of
      301, 302, 307:
        begin
          n := FoundLocationStrNum(httpsend.Headers);
          if (n >= 0) and (n <= httpsend.Headers.count) then
          begin
            httpsend.Clear;
            httpsend.HTTPMethod('GET', edt1.Text);
            Application.ProcessMessages;
            mmo1.Lines.Text := GetHTTPStr(httpsend);
            Application.ProcessMessages;
          end;
        end;
    end;

httpsend.HTTPMethod('GET', edt1.Text);
Application.ProcessMessages;
mmo1.Text:=Utf8ToAnsi(GetHTTPStr(httpsend));
end;
end.
Но в итоге в memo выгрузилось вот это:
Цитата:
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
Что нужно поправить?
Ответить с цитированием
  #2  
Старый 10.12.2013, 18:21
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Taemin
Здравствуйте, хочу научиться для себя парсить сайты с помощью Synapse. В качестве примера взял сайт pikabu. Снифером внимательно отследил данные, отправил их методом POST, залогинелся, но вот как уже под своим логином перейти на другую страницу этого ресурса и выгрузить html код страницы?
После успешного залогонивания сервер тебе должен вернуть куки (Cookies) их нужно запомнить и последующие запросы отправлять вместе с этими куками - именно так работают браузеры и другие качалки умеющие логониться.

Т.е. смотри свойство THTTPSend.Cookies
Ответить с цитированием
  #3  
Старый 10.12.2013, 19:31
Taemin Taemin вне форума
Прохожий
 
Регистрация: 07.02.2012
Сообщения: 45
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
После успешного залогонивания сервер тебе должен вернуть куки (Cookies) их нужно запомнить и последующие запросы отправлять вместе с этими куками - именно так работают браузеры и другие качалки умеющие логониться.

Т.е. смотри свойство THTTPSend.Cookies

Сделал как было предложено, в итоге и в методе POST и в методе GET используются одни и те же куки
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, httpsend, ssl_openssl, StdCtrls;

type
  TForm1 = class(TForm)
    btn1: TButton;
    mmo1: TMemo;
    edt1: TEdit;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function FoundLocationStrNum(Headers: TStringlist): integer;
var
  FoundStrPos, i: integer;
begin
  Result := -1;
  for i := 0 to Headers.Count do
  begin
    FoundStrPos := Pos('Location: ', Headers.Strings[i]);
    if FoundStrPos > 0 then
    begin
      Result := i;
      exit;
    end;
  end;
end;

function GetHTTPStr(http: THTTPSend): string;
var
  BodyStream: TStringStream;
  BodyS: TStringList;
begin
  try
    BodyS := TStringList.Create;
    BodyStream := TStringStream.Create(result);
    begin
      BodyS.LoadFromStream(http.Document);
      result := BodyS.Text;
    end;
  finally
    BodyStream.Free;
    BodyS.Free;
  end;
  http.Document.Seek(0, soFromBeginning);
end;

procedure TForm1.btn1Click(Sender: TObject);
var
      httpsend: THTTPSend;
      stream: TStringStream;
      str: TstringList;
      n: integer;
      NewURL, result: string;
      Res: boolean;

begin
str:=TstringList.Create;
httpsend:= THTTPSend.Create;
stream := TStringStream.Create('');
stream.WriteString('mode=login&username=***&password=***&remember=1');
Application.ProcessMessages;
httpsend.MimeType := 'application/x-www-form-urlencoded';
httpsend.Document.LoadFromStream(stream);
Res := httpsend.HTTPMethod('post', 'http://pikabu.ru/ajax/ajax_login.php');
str.Text:=httpsend.Cookies.Text;
httpsend.Clear;
httpsend.Cookies.Text:=str.Text;
httpsend.HTTPMethod('GET', edt1.Text);
Application.ProcessMessages;
mmo1.Text:=Utf8ToAnsi(GetHTTPStr(httpsend));
end;
end.
но выгружает совсем не то, что хотелось бы...
Цитата:
<html>
<!--LiveInternet counter--><script type="text/javascript"><!--
new Image().src = "http://counter.yadro.ru/hit?r"+
escape(document.referrer)+((typeof(screen)=="undef ined")?"":
";s"+screen.width+"*"+screen.height+"*"+(screen.co lorDepth?
screen.colorDepth:screen.pixelDepth))+";u"+escape( document.URL)+
";h"+escape(document.title.substring(0,80))+
";"+Math.random();//--></script><!--/LiveInternet-->

<body onload="challenge();">
<script>
eval(function(p,a,c,k,e,r){e=function(c){return c.toString(a)};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('1 6(){2.3=\'4=5; 0-7=8; 9=/\';a.b.c()}',13,13,'max|function|document|cookie|p hpsessien|821a5a2cc0ed0ec3e9829084c1ae2d3be7e2108e |challenge|age|43200|path|window|location|reload'. split('|'),0,{}))
</script>
</body>
</html>

В чем может быть проблема? Может из-за того, что я Гет в начале перед логином не делаю? Это вообще критично?
Ответить с цитированием
  #4  
Старый 11.12.2013, 13:52
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Цитата:
Сообщение от Taemin
Может из-за того, что я Гет в начале перед логином не делаю? Это вообще критично?
в некоторых (большинстве) случаев получение страницы авторизации абсолютно необходимо. особенно когда на ней еще всякие скрытые securitytoken есть, которые тоже распарсить придется.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #5  
Старый 11.12.2013, 17:53
Taemin Taemin вне форума
Прохожий
 
Регистрация: 07.02.2012
Сообщения: 45
Репутация: 10
По умолчанию

Все сделал, но все равно грузит какой-то странный исходный код страницы… креплю к посту исходник, посмотрите пожалуйста
Вложения
Тип файла: rar work.rar (221.5 Кбайт, 13 просмотров)
Ответить с цитированием
  #6  
Старый 12.12.2013, 11:25
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Taemin
Сделал как было предложено, в итоге и в методе POST и в методе GET используются одни и те же куки
.....
но выгружает совсем не то, что хотелось бы...
Цитата:
.....
<body onload="challenge();">
<script>
eval(function(p,a,c,k,e,r){e=function(c){return c.toString(a)};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('1 6(){2.3=\'4=5; 0-7=8; 9=/\';a.b.c()}',13,13,'max|function|document|cookie|p hpsessien|821a5a2cc0ed0ec3e9829084c1ae2d3be7e2108e |challenge|age|43200|path|window|location|reload'. split('|'),0,{}))
</script>
</body>
</html>
Похоже на саморасшифровывающийса код. Скорее всего браузеру приходит такой же ответ (нужно уточнить этот момент снифером), просто браузер (в отличие от Synapse) умеет выполнять JavaScript скрипты, поэтому такие странички открываются гладко и без запинок - можно попробовать отключить у браузера JavaScript и посмотреть сможет ли он так же безболезненно открыть этот адрес.
Ответить с цитированием
  #7  
Старый 12.12.2013, 12:37
Taemin Taemin вне форума
Прохожий
 
Регистрация: 07.02.2012
Сообщения: 45
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Похоже на саморасшифровывающийса код. Скорее всего браузеру приходит такой же ответ (нужно уточнить этот момент снифером), просто браузер (в отличие от Synapse) умеет выполнять JavaScript скрипты, поэтому такие странички открываются гладко и без запинок - можно попробовать отключить у браузера JavaScript и посмотреть сможет ли он так же безболезненно открыть этот адрес.
Посмотрел весь процесс браузера в снифере – все красиво, исходный код страницы полный. Отключил в IE JavaScript – все открывается как нужно
Изображения
Тип файла: png 111.PNG (81.0 Кбайт, 7 просмотров)
Ответить с цитированием
  #8  
Старый 12.12.2013, 12:48
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

часто бывает, что после отправки Post, в ответе идет редирект, который и возвращает нужную страницу.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #9  
Старый 12.12.2013, 13:24
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Taemin
Посмотрел весь процесс браузера в снифере – все красиво, исходный код страницы полный. Отключил в IE JavaScript – все открывается как нужно
Попробуй почистить в браузере куки (Cookies). У меня снифер показывает что приходит такой же ответ как ты выше приводил.

Вот так у меня через Mozilla Firefox:


А вот так через Internet Explorer:
Ответить с цитированием
  #10  
Старый 12.12.2013, 14:21
Taemin Taemin вне форума
Прохожий
 
Регистрация: 07.02.2012
Сообщения: 45
Репутация: 10
По умолчанию

IdHTTP тоже с JavaScript не дружит?
Меня сейчас озадачило два момента… Первый:
Код:
//===POST 2===
httpsend:=THTTPSend.Create;
httpsend.MimeType:='application/x-www-form-urlencoded';
httpsend.UserAgent:=('Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.10.229 Version/11.61');
stream := TStringStream.Create('');
stream.WriteString('i=1770882&type=+');
httpsend.Document.LoadFromStream(stream);
httpsend.Cookies.Text:=str.Text;
httpsend.HTTPMethod('post','http://pikabu.ru/ajax/dig.php' );
httpsend.Free;



Даже когда передаешь ASCII-код символа + как #043 его всеравно нет.

Второй:
Неясность с куками. Я использую для кук следующий код
Код:
str.Text:=httpsend.Cookies.Text;

и перед каждым запросом вставляю строку

Код:
httpsend.Cookies.Text:=str.Text;
При этом снифер в Get запросе совсем ничего не видит

А два разных POST при этом имеет два разных кука... что-то работает не так как должно


Ответить с цитированием
  #11  
Старый 12.12.2013, 15:58
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Taemin
IdHTTP тоже с JavaScript не дружит?
Меня сейчас озадачило два момента… Первый:
Код:
//===POST 2===
httpsend:=THTTPSend.Create;
httpsend.MimeType:='application/x-www-form-urlencoded';
httpsend.UserAgent:=('Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.10.229 Version/11.61');
stream := TStringStream.Create('');
stream.WriteString('i=1770882&type=+');
httpsend.Document.LoadFromStream(stream);
httpsend.Cookies.Text:=str.Text;
httpsend.HTTPMethod('post','http://pikabu.ru/ajax/dig.php' );
httpsend.Free;

Даже когда передаешь ASCII-код символа + как #043 его всеравно нет.
Плюс никуда не делся - он превратился в пробел. Спецсимволы в нужно кодировать в url-формате:
Код:
stream.WriteString('i=1770882&type=a%2Bb'); // Получим два параметра: "i=1770882" и "type=a+b" 
или используй функцию EncodeURLElement.
Цитата:
Сообщение от Taemin
Второй:
Неясность с куками. Я использую для кук следующий код
Код:
str.Text:=httpsend.Cookies.Text;

и перед каждым запросом вставляю строку

Код:
httpsend.Cookies.Text:=str.Text;
Значит в "str.Text" пусто, так как я не вижу на скринах чтобы в левом окне вкладки "Cookies" были какие-то значения. Левое окно этой вкладки - это те куки которые мы посылаем, а правое окно это то что сервер нам присылает в ответ. Или лучше смотри вкладку "Raw Stream" - там видно в чистом виде то что мы отправляем и получаем.
Цитата:
Сообщение от Taemin
При этом снифер в Get запросе совсем ничего не видит

А два разных POST при этом имеет два разных кука... что-то работает не так как должно
У меня этот код работает. Попробуй для примера сделать такую замену:
Код:
httpsend.Cookies.Text := 'primer=55';
Ответить с цитированием
  #12  
Старый 12.12.2013, 16:42
Taemin Taemin вне форума
Прохожий
 
Регистрация: 07.02.2012
Сообщения: 45
Репутация: 10
По умолчанию

Код:
httpsend.Cookies.Text := 'primer=55';
Эта строка работает


Делаю вот так
Код:
httpsend:=THTTPSend.Create;
httpsend.HTTPMethod('get','http://pikabu.ru' );
str.Text:=httpsend.Cookies.Text;
ShowMessage(httpsend.Cookies.Text);
Выводит пустоту... как так может быть?
Ответить с цитированием
  #13  
Старый 12.12.2013, 17:26
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Taemin
Делаю вот так
Код:
httpsend:=THTTPSend.Create;
httpsend.HTTPMethod('get','http://pikabu.ru' );
str.Text:=httpsend.Cookies.Text;
ShowMessage(httpsend.Cookies.Text);
Выводит пустоту... как так может быть?
А сниффер что говорит? Сервер куки вообще присылает?

UPD.
На работе у меня интернет через прокси, поэтому этот пример я проверить не имел возможности. Дома проверил - как я и ожидал - сервер по этому запросу никаких кук не присылает, так что вполне закономерно, что ShowMessage выводит пустоту.

Последний раз редактировалось poli-smen, 13.12.2013 в 01:13.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 13:35.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter