如何使用Delphi和Indy跟踪URL重定向?

时间:2012-06-09 14:32:09

标签: delphi url redirect query-string indy10

我收到几封带有网址链接的营销电子邮件,这些网址会从网站重定向到网站。我想编写一个程序来跟踪使用Delphi和Indy的每个URL重定向。我想遍历每个URL,记录完整的QueryString以及在此过程中可能已设置的任何Cookie。

如何使用D2010附带的Indy组件进行此操作?

1 个答案:

答案 0 :(得分:4)

首先,您需要一个HTTP客户端,在Indy中为TIdHTTP

现在您需要一个能够保存结果的数据结构:

  TRedirection = record
    queryString: String;
    cookies: TStrings;
  end;

  TRedirectionArray = array of TRedirection;

创建一个完成工作的类(需要一个类,因为事件函数定义为procedure of object):

  TRedirectionTester = class
    private
      FRedirData: TRedirectionArray;
      procedure redirectEvent(Sender: TObject; var dest: string;
        var NumRedirect: Integer; var Handled: boolean; var VMethod: TIdHTTPMethod);
      procedure newCookie(ASender: TObject; ACookie: TIdCookie; var VAccept: Boolean);
    public
      function traverseURL(url: String): TRedirectionArray;
      property RedirData: TRedirectionArray read FRedirData;
  end;

这提供了基本功能 - 您可以使用网址调用traverseURL,并返回TRedirectionArray,其中包含查询字符串和Cookie。

然后实施OnRedirect事件:

procedure TRedirectionTester.redirectEvent(Sender: TObject; var dest: string;
  var NumRedirect: Integer; var Handled: boolean; var VMethod: TIdHTTPMethod);
var
  redirDataLength: Integer;
begin
  Handled := True;

  redirDataLength := Length(FRedirData);
  SetLength(FRedirData, redirDataLength + 1);

  FRedirData[redirDataLength].queryString := dest;
  FRedirData[redirDataLength].cookies := TStringList.Create;
end;

这将在数组中添加一个条目,并存储重定向的查询字符串。由于此重定向本身不包含cookie(在请求重定向页面时设置了cookie),因此您无法在此处添加任何cookie。

这就是为什么你需要一个OnNewCookie处理程序:

procedure TRedirectionTester.newCookie(ASender: TObject; ACookie: TIdCookie; var VAccept: Boolean);
var
  redirDataLength: Integer;
begin
  VAccept := True;

  redirDataLength := High(FRedirData);
  if (Assigned(FRedirData[redirDataLength].cookies)) then
    FRedirData[redirDataLength].cookies.Add(ACookie.CookieText);
end;

这只会将CookieText添加到数据集中。该字段包含cookie的“摘要” - 它是请求页面时发送的实际字符串数据。

最后,通过实施traverseURL函数将其组合在一起:

function TRedirectionTester.traverseURL(url: String): TRedirectionArray;
var
  traverser: TIdHTTP;
begin
  traverser := TIdHTTP.Create();
  traverser.HandleRedirects := True;
  traverser.OnRedirect := redirectEvent;
  traverser.CookieManager := TIdCookieManager.Create();
  traverser.CookieManager.OnNewCookie := newCookie;

  SetLength(FRedirData, 1);
  FRedirData[0].queryString := url;
  FRedirData[0].cookies := TStringList.Create;

  traverser.Get(url);

  Result := FRedirData;
end;

它没有做太多:它创建所需的对象,并分配事件处理程序。然后它添加第一个url作为第一个重定向(即使它不是真正的重定向,我添加它是为了完整性)。 然后,对Get的调用会发送请求。它将在网页服务器找到并返回最终页面后返回。

我用http://bit.ly/Lb2Vho测试了它。

然而,这仅处理由HTTP状态代码301或302引起的重定向。据我所知,它不处理通过<meta>标记或javascript完成的重定向。 要添加该功能,您必须检查对Get的调用结果,并解析该搜索以查找此类重定向。