我收到几封带有网址链接的营销电子邮件,这些网址会从网站重定向到网站。我想编写一个程序来跟踪使用Delphi和Indy的每个URL重定向。我想遍历每个URL,记录完整的QueryString以及在此过程中可能已设置的任何Cookie。
如何使用D2010附带的Indy组件进行此操作?
答案 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
的调用结果,并解析该搜索以查找此类重定向。