zoukankan      html  css  js  c++  java
  • delphi idhttp 实战用法(TIdhttpEx)

    以delphi XE8 自带indy(10.5.8.0)组件为例,分享实战中遇到的问题及解决方法。

    TIdHttpEx 用法实例01[多线程获取网页](包含完整源码)

    实例02(如何Post参数,如何保存与提取Cookie)待写

    TIdHttpEx 已实现了对GZIP的解压,对UTF-8编码解码等

    本文包含以下几个单元

    uIdhttp.pas (TIdHttpEx)

    uIdCookieMgr.pas (TIdCookieMgr)

    uOperateIndy.pas 操作 TIdhttpEx 全靠它了

    uIdhttp.Pas

     1 unit uIdHttpEx;
     2 
     3 interface
     4 
     5 uses
     6   Classes, Idhttp, uIdCookieMgr, IdSSLOpenSSL;
     7   {uIdCookieMgr 是我改进的}
     8 
     9 type
    10 
    11   TIdhttpEx = class(TIdhttp)
    12   private
    13     FIdCookieMgr: TIdCookieMgr;
    14     FIdSSL: TIdSSLIOHandlerSocketOpenSSL;
    15   public
    16     constructor Create(AOwner: TComponent);
    17     property CookieMgr: TIdCookieMgr read FIdCookieMgr;
    18     procedure GenRandomUserAgent; //随便生成一个请求头,可以忽略或自己改进
    19     property IdSSL: TIdSSLIOHandlerSocketOpenSSL read FIdSSL;
    20 
    21   end;
    22 
    23 implementation
    24 
    25 { TIdhttpEx }
    26 
    27 const
    28 
    29   sUserAgent =
    30     'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 2.0.50727)';
    31   // sAccept = 'image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, */*';
    32   sUserAgent2 =
    33     'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; InfoPath.3; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)';
    34   sAccept = 'application/x-shockwave-flash, image/gif, image/jpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*';
    35 
    36   sUserAgent3 =
    37     'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36';
    38   sAccept2 = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
    39 
    40   MaxUserAgentCount = 3;
    41 
    42 var
    43   UserAgent: array [0 .. MaxUserAgentCount - 1] of string;
    44 
    45 constructor TIdhttpEx.Create(AOwner: TComponent);
    46 begin
    47   inherited;
    48 
    49   HTTPOptions := []; // 禁止POST参数编码,自己手动编 HttpEncodeX
    50 
    51   // HTTPOptions := [hoNoParseMetaHTTPEquiv]; // 禁止POST参数编码,自己手动编 HttpEncodeX
    52   // hoNoParseMetaHTTPEquiv 禁止解析html 此可能造成假死!
    53 
    54   FIdCookieMgr := TIdCookieMgr.Create(self);
    55   CookieManager := FIdCookieMgr;
    56 
    57   // ssl 需要 libeay32.dll ssleay32.dll 阿里旺旺目录下可以搜索到
    58 
    59   FIdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(self);
    60   IOHandler := FIdSSL;
    61 
    62   HandleRedirects := true;
    63   AllowCookies := true;
    64   ProtocolVersion := pv1_1;
    65 
    66   Request.RawHeaders.FoldLength := 25000; // 参数头长度,重要
    67 
    68   ReadTimeout := 15000;
    69   ConnectTimeout := 15000;
    70 
    71   RedirectMaximum := 5;
    72   Request.UserAgent := sUserAgent3;
    73   Request.Accept := sAccept;
    74   Request.AcceptEncoding := 'gzip';
    75 
    76 end;
    77 
    78 procedure TIdhttpEx.GenRandomUserAgent;
    79 begin
    80   Randomize;
    81   self.Request.UserAgent := UserAgent[Random(MaxUserAgentCount)];
    82 end;
    83 
    84 initialization
    85 
    86 UserAgent[0] :=
    87   'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 2.0.50727)';
    88 UserAgent[1] :=
    89   'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; InfoPath.3; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)';
    90 UserAgent[2] :=
    91   'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36';
    92 
    93 // 这三句请忽略,有些网站认求头,我随便写的。请大家根本实际情况改进
    94 finalization
    95 
    96 end.
    uIdhttpEx.pas

    uIdCookieMgr.Pas

      1 unit uIdCookieMgr;
      2 
      3 interface
      4 
      5 uses
      6   IdCookieManager, Classes;
      7 
      8 type
      9   TIdCookieMgr = class(TIdCookieManager)
     10   private
     11 
     12     procedure SetCurCookies(const Value: string);
     13 
     14     function GetCurCookies: string;
     15     function GetCookieList: TStringList;
     16 
     17   public
     18 
     19     procedure SaveCookies(const AFileName: string);
     20     procedure LoadCookies(const AFileName: string);
     21 
     22     function GetCookieValue(const ACookieName: string): string;
     23     property CurCookies: string read GetCurCookies write SetCurCookies;
     24 
     25   end;
     26 
     27 implementation
     28 
     29 uses
     30   IdCookie, SysUtils, IdURI, uStrUtils, IdGlobalProtocols, DateUtils;
     31 { uStrUtils 一套操作字串的函数单元 }
     32 
     33 function TIdCookieMgr.GetCookieList: TStringList;
     34 var
     35   C: Tcollectionitem;
     36 begin
     37   result := TStringList.Create;
     38   for C in CookieCollection do
     39     result.add((C as TIdCookie).CookieText);
     40 end;
     41 
     42 function TIdCookieMgr.GetCookieValue(const ACookieName: string): string;
     43 var
     44   n: integer;
     45 begin
     46   result := '';
     47   if IsNotEmptyStr(ACookieName) then
     48   begin
     49     n := CookieCollection.GetCookieIndex(ACookieName);
     50     if n >= 0 then
     51       result := CookieCollection.Cookies[n].Value;
     52   end;
     53 end;
     54 
     55 function TIdCookieMgr.GetCurCookies: string;
     56 var
     57   strs: TStringList;
     58 begin
     59   strs := GetCookieList;
     60   try
     61     result := strs.Text;
     62   finally
     63     strs.Free;
     64   end;
     65 end;
     66 
     67 procedure TIdCookieMgr.LoadCookies(const AFileName: string);
     68 var
     69   StrLst: TStringList;
     70   C: TIdCookie;
     71   uri: TIdURI;
     72   s, t: string;
     73 begin
     74   StrLst := TStringList.Create;
     75   uri := TIdURI.Create;
     76   try
     77     if FileExists(AFileName) then
     78     begin
     79       StrLst.LoadFromFile(AFileName);
     80       for s in StrLst do
     81       begin
     82         C := CookieCollection.add;
     83         CookieCollection.AddCookie(C, uri);
     84         C.ParseServerCookie(s, uri);
     85         C.Domain := GetStrBetween(s, 'Domain=', ';');
     86         C.Path := GetStrBetween(s, 'Path=', ';');
     87         t := GetStrBetween(s, 'Expires=', 'GMT') + 'GMT'; // GetStrBetween 在 uStrUtils 单元中
     88         C.Expires := CookieStrToLocalDateTime(t);
     89       end;
     90     end;
     91   finally
     92     uri.Free;
     93     StrLst.Free;
     94   end;
     95 end;
     96 
     97 procedure TIdCookieMgr.SaveCookies(const AFileName: string);
     98 var
     99   StrLst: TStringList;
    100 begin
    101   StrLst := GetCookieList;
    102   try
    103     StrLst.SaveToFile(AFileName);
    104   finally
    105     StrLst.Free;
    106   end;
    107 end;
    108 
    109 procedure TIdCookieMgr.SetCurCookies(const Value: string);
    110 var
    111   StrLst: TStringList;
    112   C: TIdCookie;
    113   uri: TIdURI;
    114   s, t: string;
    115 begin
    116   StrLst := TStringList.Create;
    117   uri := TIdURI.Create;
    118   try
    119     StrLst.Text := Value;
    120     CookieCollection.Clear;
    121     for s in StrLst do
    122     begin
    123       C := CookieCollection.add;
    124       CookieCollection.AddCookie(C, uri);
    125       C.ParseServerCookie(s, uri);
    126       C.Domain := GetStrBetween(s, 'Domain=', ';');
    127       C.Path := GetStrBetween(s, 'Path=', ';');
    128       t := GetStrBetween(s, 'Expires=', 'GMT') + 'GMT';
    129       C.Expires := CookieStrToLocalDateTime(t);
    130     end;
    131   finally
    132     uri.Free;
    133     StrLst.Free;
    134   end;
    135 end;
    136 
    137 end.
    uIdCookeMgr.pas

    uOperateIndy.pas 非常有用操作 TIdhttpEx 全靠它了

      1 unit uOperateIndy;
      2 
      3 interface
      4 
      5 uses
      6   Classes, Idhttp, IdMultipartFormData;
      7 
      8 function IdhttpGet(AIdhttp: TIdHTTP; AUrl: string; var AHtml: string): Boolean;
      9 function IdhttpPost(AIdhttp: TIdHTTP; AStrList: TStringList; AUrl: string; var AHtml: String)
     10   : Boolean; overload;
     11 function IdhttpPost(AIdhttp: TIdHTTP; AIdMul: TIdMultiPartFormDataStream; AUrl: string;
     12   var AHtml: string): Boolean; overload;
     13 
     14 function GetHtmlFromUrl(AUrl: string; var AHtml: string): Boolean;
     15 
     16 implementation
     17 
     18 uses
     19   uIdhttpEx, SysUtils, ZLibEx, StrUtils, uStrUtils, uHtmlElement, uParseHtml;
     20 { 带u的单元,都是我写的,ZLibEx 是解压库 }
     21 
     22 //解压GZIP 那个参数31是试出来的
     23 procedure DecompressGZIP(inStream, outStream: TStream); inline;
     24 begin
     25   ZDecompressStream2(inStream, outStream, 31);
     26 end;
     27 
     28 function HtmlIsUTF8(AHtml: string): Boolean;
     29 var
     30   BMetaList: TSingleHtmlElementList;
     31   BMeta: TSingleHtmlElement;
     32   BKeyElement: PKeyElement;
     33   BCheckOver: Boolean;
     34   sKeyName: string;
     35   sKeyValue: string;
     36 begin
     37   Result := false;
     38   BMetaList := TSingleHtmlElementList.Create;
     39   try
     40 
     41     GetMetaList(AHtml, BMetaList);
     42 
     43     BCheckOver := false;
     44 
     45     for BMeta in BMetaList do
     46     begin
     47 
     48       for BKeyElement in BMeta.KeyElementList do
     49       begin
     50 
     51         sKeyName := UpperCase(BKeyElement.Name);
     52         sKeyValue := UpperCase(BKeyElement.Value);
     53 
     54         if PosEx('UTF-8', sKeyValue) > 0 then
     55         begin
     56           Result := true;
     57           BCheckOver := true;
     58           break;
     59         end;
     60 
     61       end;
     62 
     63       if BCheckOver then
     64         break;
     65     end;
     66 
     67   finally
     68     BMetaList.Free;
     69   end;
     70 end;
     71 
     72 function GetHtmlAfterOperateIdhttp(AIdhttp: TIdHTTP; AStream: TStream): string;
     73 var
     74   BSize: Int64;
     75   BOutStream: TMemoryStream;
     76   TempStream: TMemoryStream;
     77   rS: RawByteString;
     78   s: string;
     79   sUtf8: string;
     80   BIsUtf8: Boolean;
     81   sCharSet: string;
     82 
     83 begin
     84   BSize := AStream.Size;
     85 
     86   BOutStream := TMemoryStream.Create;
     87   try
     88     if BSize > 0 then
     89     begin
     90 
     91       if PosEx('GZIP', UpperCase(AIdhttp.Response.ContentEncoding)) > 0 then
     92       begin
     93         AStream.Position := 0;
     94         DecompressGZIP(AStream, BOutStream);
     95         TempStream := BOutStream;
     96       end
     97       else
     98         TempStream := TMemoryStream(AStream);
     99 
    100       BSize := TempStream.Size;
    101       SetLength(rS, BSize);
    102       TempStream.Position := 0;
    103       TempStream.ReadBuffer(rS[1], BSize);
    104 
    105       s := string(rS);
    106       sUtf8 := UTF8ToString(rS);
    107 
    108       sCharSet := AIdhttp.Response.CharSet;
    109       BIsUtf8 := PosEx('UTF-8', UpperCase(sCharSet)) > 0;
    110       if not BIsUtf8 then
    111         BIsUtf8 := HtmlIsUTF8(s);
    112 
    113       if BIsUtf8 then
    114         Result := sUtf8
    115       else
    116       begin
    117 
    118         if (PosEx('', sUtf8) > 0) or (PosEx('', sUtf8) > 0) or (PosEx('', sUtf8) > 0) or
    119           (PosEx('', sUtf8) > 0) or (PosEx('我们', sUtf8) > 0) or (PosEx('', sUtf8) > 0) or
    120           (PosEx('', sUtf8) > 0) then
    121 
    122         begin
    123           Result := sUtf8;
    124         end
    125         else
    126           Result := s;
    127 
    128       end;
    129 
    130     end
    131   finally
    132     BOutStream.Free;
    133   end;
    134 
    135 end;
    136 
    137 function IdhttpGet(AIdhttp: TIdHTTP; AUrl: string; var AHtml: string): Boolean;
    138 var
    139   BStrStream: TMemoryStream;
    140 begin
    141   AHtml := '';
    142   BStrStream := TMemoryStream.Create;
    143   try
    144     try
    145       AIdhttp.Get(AUrl, BStrStream);
    146       AHtml := GetHtmlAfterOperateIdhttp(AIdhttp, BStrStream);
    147       Result := true;
    148     except
    149       on e: Exception do
    150       begin
    151         Result := false;
    152         AHtml := e.Message;
    153       end;
    154     end;
    155   finally
    156     BStrStream.Free;
    157   end;
    158 end;
    159 
    160 function IdhttpPost(AIdhttp: TIdHTTP; AStrList: TStringList; AUrl: string; var AHtml: String)
    161   : Boolean; overload;
    162 var
    163   BStrStream: TMemoryStream;
    164 begin
    165   Result := true;
    166   AHtml := '';
    167   BStrStream := TMemoryStream.Create;
    168   try
    169     try
    170       AIdhttp.Post(AUrl, AStrList, BStrStream);
    171       AHtml := GetHtmlAfterOperateIdhttp(AIdhttp, BStrStream);
    172     except
    173       on e: Exception do
    174       begin
    175         AHtml := e.Message;
    176         Result := false;
    177       end;
    178     end;
    179   finally
    180     BStrStream.Free;
    181   end;
    182 end;
    183 
    184 function IdhttpPost(AIdhttp: TIdHTTP; AIdMul: TIdMultiPartFormDataStream; AUrl: string;
    185   var AHtml: string): Boolean; overload;
    186 var
    187   BStrStream: TMemoryStream;
    188 begin
    189   Result := true;
    190   AHtml := '';
    191   BStrStream := TMemoryStream.Create;
    192   try
    193     try
    194       AIdhttp.Post(AUrl, AIdMul, BStrStream);
    195       AHtml := GetHtmlAfterOperateIdhttp(AIdhttp, BStrStream);
    196     except
    197       on e: Exception do
    198       begin
    199         AHtml := e.Message;
    200         Result := false;
    201       end;
    202     end;
    203   finally
    204     BStrStream.Free;
    205   end;
    206 end;
    207 
    208 function GetHtmlFromUrl(AUrl: string; var AHtml: string): Boolean;
    209 var
    210   Idhttp: TIdhttpEx;
    211 begin
    212   Idhttp := TIdhttpEx.Create(nil);
    213   try
    214     Result := IdhttpGet(Idhttp, AUrl, AHtml);
    215   finally
    216     Idhttp.Free;
    217   end;
    218 end;
    219 
    220 end.
    uOperateIndy.pas

    附:delphi 进阶基础技能说明

  • 相关阅读:
    图文详解k8s自动化持续集成之GitLab CI/CD
    GitLab CI/CD 进行持续集成
    高性能伪事务之Lua in Redis
    面向对象之组合VS继承:继承过时了?
    Go依赖模块版本之Module避坑使用详解
    Maven3路程(三)用Maven创建第一个web项目(1)
    C#通过WIN32 API实现嵌入程序窗体
    Selenium自動化測試(Python+VS2013)-基礎篇-環境安裝
    VS2013中Python学习笔记[环境搭建]
    win7 windows server 2008R2下 https SSL证书安装的搭配(搭配https ssl本地测试环境)
  • 原文地址:https://www.cnblogs.com/lackey/p/4085131.html
Copyright © 2011-2022 走看看