Как получить внутренний HTML с помощью INDY - PullRequest
0 голосов
/ 07 июля 2011

Я застрял в этой проблеме: мне нужно получить время и дату со страницы presnycas.eu (для синхронизации).Дата в порядке, но я не могу получить время.Проблема в том, что когда я вызываю метод IdHTTP.Get(..), в результате я получаю HTML-код страницы, но времени не хватает.Вот так:

<div class="boxik"> 
<table style="text-align: left; width: 700px; height: 116px;" border="0" cellpadding="2" cellspacing="0"> 
  <tbody> 
    <tr> 
      <td style="width: 400px;" colspan="1" rowspan="5"> 
            <div class="hodinyhlavni"> 

            <span id="servertime"></span> 
              // This is where the time should be - when viewed with 
              // developer tools in Chrome, it does show the time
              // (picture here http://img684.imageshack.us/img684/166/pagem.png)
            </div> 
      </td> 
      <td style="width: 0px;"> &nbsp;      
           07.07.2011
      </td> 

Теперь я использую неловкий подход - я загружаю TWebBrowser и затем вызываю

Time:=StrToTime(WebBrowser1.OleObject.Document.GetElementByID('servertime').innerhtml);

, но это довольно медленно, и я бы не стал использовать TWebBrowserвообще.

Итак, как я могу получить innerhtml элемента с помощью вызова функции?

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

Ответы [ 3 ]

1 голос
/ 07 июля 2011

Наиболее важной частью этого ответа будет «вам нужно понять HTML и JavaScript и выяснить, как работает сайт». Откройте веб-сайт, щелкните правой кнопкой мыши и выполните «Показать источник». Вы заметите это наверху:

<script type="text/javascript">var currenttime = 'July 07, 2011 11:51:14'</script>

Это похоже на время, и в моем случае время правильное, но не настроено на МОЙ часовой пояс. Вы можете легко получить обычный HTML-код с помощью Indy, и этого достаточно. Этот быстрый пример кода показывает, как захватить HTML и разобрать дату и время, используя небольшой кусочек RegEx. Если вы используете Delphi XE, вам придется заменить имя класса TPerlRegEx и имя устройства PerlRegEx на все, что захочет XE. Если вы используете более старую версию Delphi, это не повод НЕ использовать RegEx! Загрузите TPerlRegEx, это бесплатно и совместимо с XE.

program Project29;

{$APPTYPE CONSOLE}

uses
  SysUtils, IdHTTP, PerlRegEx, SysConst;

function ExtractDayTime: TDateTime;
var H: TIdHTTP;
    Response: string;
    RegEx: TPerlRegEx;

    s: string;

    Month, Year, Day, Hour, Minute, Second: Word;
begin
  H := TIdHttp.Create(Nil);
  try
    Response := H.Get('http://presnycas.eu/');
    RegEx := TPerlRegEx.Create;
    try
      RegEx.RegEx := 'var\ currenttime\ \=\ \''(\w+)\ (\d{1,2})\,\ (\d{4})\ (\d{1,2})\:(\d{1,2})\:(\d{1,2})\''';
      RegEx.Subject := Response;
      if RegEx.Match then
        begin

          // Translate month
          s := RegEx.Groups[1];
          if s = SShortMonthNameJan then Month := 1

          else if s = SShortMonthNameFeb then Month := 2
          else if s = SShortMonthNameMar then Month := 3
          else if s = SShortMonthNameApr then Month := 4
          else if s = SShortMonthNameMay then Month := 5
          else if s = SShortMonthNameJun then Month := 6
          else if s = SShortMonthNameJul then Month := 7
          else if s = SShortMonthNameAug then Month := 8
          else if s = SShortMonthNameSep then Month := 9
          else if s = SShortMonthNameOct then Month := 10
          else if s = SShortMonthNameNov then Month := 11
          else if s = SShortMonthNameDec then Month := 12

          else if s = SLongMonthNameJan then Month := 1
          else if s = SLongMonthNameFeb then Month := 2
          else if s = SLongMonthNameMar then Month := 3
          else if s = SLongMonthNameApr then Month := 4
          else if s = SLongMonthNameMay then Month := 5
          else if s = SLongMonthNameJun then Month := 6
          else if s = SLongMonthNameJul then Month := 7
          else if s = SLongMonthNameAug then Month := 8
          else if s = SLongMonthNameSep then Month := 9
          else if s = SLongMonthNameOct then Month := 10
          else if s = SLongMonthNameNov then Month := 11
          else if s = SLongMonthNameDec then Month := 12

          else
            raise Exception.CreateFmt('Don''t know what month is: %s', [s]);

          // Day, Year, Hour, Minute, Second
          Day := StrToInt(RegEx.Groups[2]);
          Year := StrToInt(RegEx.Groups[3]);
          Hour := StrToInt(RegEx.Groups[4]);
          Minute := StrToInt(RegEx.Groups[5]);
          Second := StrToInt(RegEx.Groups[6]);

          Result := EncodeDate(Year, Month, Day) + EncodeTime(Hour, Minute, Second, 0);

        end
      else
        raise Exception.Create('Can''t get time!');
    finally RegEx.Free;
    end;
  finally H.Free;
  end;
end;

begin
  WriteLn(DateTimeToStr(ExtractDayTime));
  ReadLn;
end.
1 голос
/ 07 июля 2011

Я попробовал указанную вами ссылку (http://presnycas.eu/)), и из HTML я вижу, что фактическое время возвращается в другом месте в HTML, а затем увеличивается локально с помощью JavaScript, поэтому вам нужно "получить" новый время, если вы хотите синхронизировать.

Найдите это в HTML (внутри элемента HEAD):

<head>
...
<script type="text/javascript">var currenttime = 'July 07, 2011 12:01:26'</script>
...
</head>
0 голосов
/ 30 октября 2015

Как получить внутренний html используя indy TidHTTP

var
  Form2: TForm2;
  xpto:tmemorystream;
  xx:string;
  implementation

{$R *.fmx}

procedure TForm2.Button1Click(Sender: TObject);

begin
xpto:=tmemorystream.Create;
idhttp1.Get('http://google.com',xpto);
xpto.Position:=0;

end;


procedure TForm2.IdHTTP1WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
var x:string;
begin

SetString(x, PAnsiChar(xpto.Memory), xpto.Size);

memo1.Lines.add(x);
end;

// Для использования Android Firemonkey замените Pansichar на MarshaledAString

...