4

我正在尝试从用户个人资料中下载所有问题和答案,但是有一个问题,如果用户有大量问题,我必须单击“显示更多”以展开该列表。例如,如果我尝试下载这个人的问题和答案:http ://ask.fm/UnaRamekic (随机选择),我只会得到那些显示的,那些在我点击显示更多后显示的不是用获取请求检索的。我怎样才能得到ICS 或 Indy 组件的所有问题。谢谢。

我的代码:

procedure TForm1.sButton1Click(Sender: TObject);
begin
With HttpCli1 do begin
    URL            := sedit1.Text;
    RequestVer     := '1.1';
    RcvdStream := TMemoryStream.Create;
    try
        Get;
    except
        ShowMessage('There has been an error , check your internet connection !');
        RcvdStream.Free;
        Exit;
    end;

    RcvdStream.Seek(0,0);
    Memo1.Lines.LoadFromStream(RcvdStream);
    RcvdStream.Free;
 end;
 end;
4

2 回答 2

1

单独使用 Indy 或 ICS 将无法做到这一点。您最初看到的正是您拉取 HTTP 请求时正在下载的内容。

如果您查看页面的 HTML 源代码,您会看到“查看更多”按钮附加了一个 JavaScript 事件处理程序,该处理程序向服务器发出 AJAX 请求,从中提取更多数据,并将其应用于页。如果你想做同样的事情,你的代码需要至少解析出足够的东西以获得正确的 AJAX 参数,然后像任何其他 HTTP 请求一样从你的 Indy 或 ICS 代码向服务器发出请求,并处理回来。

于 2012-08-31T22:56:13.500 回答
1

警告:

这种方法是蹩脚的,而且相当危险。它与“显示更多”按钮类似地发布表单数据,但它使用一个 while 循环(接收所有页面),该循环重复直到找到响应中的确切常量(在代码中它是LastPageResponse常量),所以当响应内容页面将在一段时间内更改,并且该常量不会出现在响应中,您会发现自己处于无限循环中。

GetAllQuestions函数中,您可以指定:

  • AUser - 是 URL 中斜杠后的用户名
  • AFromDate - 是您想要从中获取结果的开始日期时间
  • AStartPage - 是您想要从中获取结果的 AFromDate 日期时间的起始页面

GetAllQuestions函数返回一个基本用户的页面,后跟换行符分隔的内容,范围从基本页面到您指定的时间和页面中的所有页面。忘了注意,您需要以不同于基本页面的方式解析的附加内容,因为它不是 HTML 内容。

uses
  IdHTTP;

implementation

function GetAllQuestions(const AUser: string; AFromDate: TDateTime;
  AStartPage: Integer = 1): string;
var
  Response: string;
  LastPage: Integer;
  TimeString: string;
  HTTPClient: TIdHTTP;
  Parameters: TStrings;
const
  LineBreaks = sLineBreak + sLineBreak;
  LastPageResponse = '$("#more-container").hide();';
begin
  Result := '';
  HTTPClient := TIdHTTP.Create(nil);
  try
    Result := HTTPClient.Get('http://ask.fm/' + AUser) + LineBreaks;
    Parameters := TStringList.Create;
    try
      LastPage := AStartPage;
      TimeString := FormatDateTime('ddd mmm dd hh:nn:ss UTC yyyy', AFromDate);
      Parameters.Add('time=' + TimeString);
      Parameters.Add('page=' + IntToStr(LastPage));
      while LastPage <> -1 do
      begin
        Parameters[1] := 'page=' + IntToStr(LastPage);
        Response := HTTPClient.Post('http://ask.fm/' + AUser + '/more',
          Parameters);
        if Copy(Response, Length(Response) - Length(LastPageResponse) + 1,
          MaxInt) = LastPageResponse
        then
          LastPage := -1
        else
          LastPage := LastPage + 1;
        Result := Result + Response + LineBreaks;
      end;
    finally
      Parameters.Free;
    end;
  finally
    HTTPClient.Free;
  end;
end;

以及用法:

procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    Memo1.Text := GetAllQuestions('TLama', Now);
  except
    on E: Exception do
      ShowMessage(E.Message);
  end;
end;
于 2012-08-31T23:00:39.490 回答