Unit1.~pas
上传用户:zstyzgs
上传日期:2008-06-25
资源大小:214k
文件大小:10k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit Unit1;
  2. interface
  3. uses
  4.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  5.   Dialogs, StdCtrls, WinHTTP, SyncObjs, ExtCtrls, ComCtrls, Spin;
  6. type
  7.   TMyThread = class(TThread)
  8.   private
  9.     FHTTP: TWinHTTP;
  10.     FEvent: TEvent;
  11.     FHTML: string;
  12.     FEntryURL: string;
  13.     FURL: string;
  14.     FURLs: TStrings;
  15.     FData: TStrings;
  16.     function GetURLs(const AURL: string): string;
  17.     procedure HTTPDone(Sender: TObject; const ContentType: string;
  18.       FileSize: Integer; Stream: TStream);
  19.     procedure AddURL;
  20.     procedure AddData;
  21.     procedure AddURLs;
  22.     procedure GetURL;
  23.     function IsURL(const AURL: string): Boolean;
  24.     function ParseString(const ARE, AInputString, ATemplate: string): string;
  25.       overload;
  26.     function ParseString(const ARE, AInputString: string): string; overload;
  27.     function ParseEmails(const ARE, AInputString: string): string;
  28.   protected
  29.     procedure Execute; override;
  30.     procedure DoTerminate; override;
  31.     procedure Terminate;
  32.   public
  33.     constructor Create(const AEntryURL: string = '');
  34.     destructor Destroy; override;
  35.   end;
  36.   TForm1 = class(TForm)
  37.     WinHTTP1: TWinHTTP;
  38.     Memo1: TMemo;
  39.     StatusBar1: TStatusBar;
  40.     Panel1: TPanel;
  41.     Edit1: TEdit;
  42.     Button1: TButton;
  43.     Button2: TButton;
  44.     Label1: TLabel;
  45.     SpinEdit1: TSpinEdit;
  46.     Memo2: TMemo;
  47.     procedure FormCreate(Sender: TObject);
  48.     procedure FormDestroy(Sender: TObject);
  49.     procedure Button1Click(Sender: TObject);
  50.     procedure Button2Click(Sender: TObject);
  51.     procedure Memo1Change(Sender: TObject);
  52.     procedure Edit1Change(Sender: TObject);
  53.   private
  54.     FList: TThreadList;
  55.     FLock: TCriticalSection;
  56.     FIndex: Integer;
  57.     procedure RemoveThread(Sender: TMyThread);
  58.   public
  59.     procedure Lock;
  60.     procedure Unlock;
  61.     function GetURL(var AURL: string): Boolean;
  62.   end;
  63. var
  64.   Form1: TForm1;
  65. const
  66.   URLRE =
  67.     '<[aAscriptSCRIPTiframeIFRAMElinkLINK]{1,6}.*?[hrefHREFsrcSRC]{3,4}s*=s*["''s]*(.*?)["''s>]+.*?>';
  68.   URLPathRE = '((http://)*[w+][.w]+[w/.:-]*/)';
  69.   URLHostRE = '((http://)*[w+][.w-]+[w.:]*)';
  70.   EmailRE = '([_a-zA-Zd-.]+[@#][_a-zA-Zd-]+(.[_a-zA-Zd-]+)+)';
  71. implementation
  72. uses RegExpr;
  73. {$R *.dfm}
  74. { TForm1 }
  75. procedure TForm1.FormCreate(Sender: TObject);
  76. begin
  77.   FList := TThreadList.Create;
  78.   FLock := TCriticalSection.Create;
  79. end;
  80. procedure TForm1.FormDestroy(Sender: TObject);
  81. begin
  82.   if Assigned(FLock) then
  83.     FLock.Free;
  84.   if Assigned(FList) then
  85.     FList.Free;
  86. end;
  87. procedure TForm1.RemoveThread(Sender: TMyThread);
  88. var
  89.   List: TList;
  90. begin
  91.   List := FList.LockList;
  92.   try
  93.     List.Remove(Sender);
  94.   finally
  95.     FList.UnlockList;
  96.   end;
  97. end;
  98. procedure TForm1.Lock;
  99. begin
  100.   FLock.Enter;
  101. end;
  102. procedure TForm1.Unlock;
  103. begin
  104.   FLock.Leave;
  105. end;
  106. function TForm1.GetURL(var AURL: string): Boolean;
  107. begin
  108.   Lock;
  109.   try
  110.     Result := FIndex < Memo1.Lines.Count;
  111.     if Result then
  112.     begin
  113.       AURL := Memo1.Lines.Strings[FIndex];
  114.       Inc(FIndex);
  115.     end;
  116.   finally
  117.     Unlock;
  118.   end;
  119. end;
  120. { TMyThread }
  121. procedure TMyThread.AddURL;
  122. begin
  123.   if (Form1.Memo1.Lines.IndexOf(FURL) = -1) and IsURL(FURL) then
  124.   begin
  125.     Form1.Memo1.Lines.Add(FURL);
  126.     Application.ProcessMessages;
  127.   end;
  128. end;
  129. constructor TMyThread.Create(const AEntryURL: string);
  130. begin
  131.   FHTTP := TWinHTTP.Create(nil);
  132.   FHTTP.OnDone := HTTPDone;
  133.   FEvent := TEvent.Create(nil, True, False, '');
  134.   FEntryURL := AEntryURL;
  135.   FData := TStringList.Create;
  136.   FURLs := TStringList.Create;
  137.   FreeOnTerminate := True;
  138.   inherited Create(True);
  139. end;
  140. destructor TMyThread.Destroy;
  141. begin
  142.   if Assigned(FURLs) then
  143.     FURLs.Free;
  144.   if Assigned(FData) then
  145.     FData.Free;
  146.   if Assigned(FEvent) then
  147.     FEvent.Free;
  148.   if Assigned(FHTTP) then
  149.     FHTTP.Free;
  150.   inherited;
  151. end;
  152. procedure TMyThread.DoTerminate;
  153. begin
  154.   Form1.RemoveThread(Self);
  155.   inherited;
  156. end;
  157. procedure TMyThread.Execute;
  158. var
  159.   url: string;
  160. begin
  161.   while not Terminated do
  162.   begin
  163.     if not Form1.GetURL(url) then
  164.       ;
  165.     //Break;
  166.     FEvent.ResetEvent;
  167.     GetURLs(url);
  168.   end;
  169. end;
  170. function TMyThread.GetURLs(const AURL: string): string;
  171. {var
  172.   re: TRegExpr;
  173.   HTML: string;}
  174. begin
  175.   FHTTP.URL := AURL;
  176.   FHTTP.Referer := AURL;
  177.   FHTTP.Read();
  178.   FEvent.WaitFor(10000);
  179.   //FEvent.WaitFor(INFINITE);
  180.   //HTML := FHTML;
  181.   //FData.CommaText := ParseEmails(EmailRE, FHTML);
  182.   //Synchronize(AddData);
  183.   FURLs.CommaText := ParseString(URLRE, FHTML);
  184.   Synchronize(AddURLs);
  185.   {try
  186.     re := TRegExpr.Create;
  187.     try
  188.       re.Expression := URLRE;
  189.       if re.Exec(FHTML) then
  190.       repeat
  191.         FURL := re.Match[1];
  192.         if not IsURL(FURL) then Continue;
  193.         if FURL[1] = '/' then
  194.           FURL := ParseString(URLHostRE, AURL, '$1') + FURL
  195.         else if LowerCase(Copy(FURL, 1, 4)) <> 'http' then
  196.           FURL := ParseString(URLPathRE, AURL, '$1') + FURL;
  197.         Synchronize(AddURL);
  198.         //Sleep(5);
  199.         //GetData(FURL);
  200.         if Terminated then
  201.           Exit;
  202.       until not re.ExecNext;
  203.     finally
  204.       re.Free;
  205.     end;
  206.   except
  207.   end;}
  208.   Result := FHTML;
  209. end;
  210. procedure TMyThread.GetURL;
  211. var
  212.   RE: TRegExpr;
  213. begin
  214.   re := TRegExpr.Create;
  215.   try
  216.     re.Expression := URLRE;
  217.     if re.Exec(FHTML) then
  218.       repeat
  219.         FURL := re.Match[1];
  220.         Synchronize(AddURL);
  221.         if Terminated then
  222.           Exit;
  223.       until not re.ExecNext;
  224.   finally
  225.     re.Free;
  226.   end;
  227. end;
  228. procedure TMyThread.HTTPDone(Sender: TObject; const ContentType: string;
  229.   FileSize: Integer; Stream: TStream);
  230. var
  231.   Str: string;
  232. begin
  233.   with Stream as TMemoryStream do
  234.   begin
  235.     SetLength(Str, Size);
  236.     Move(Memory^, Str[1], Size);
  237.     FHTML := Str;
  238.     FEvent.SetEvent;
  239.   end
  240. end;
  241. function TMyThread.ParseString(const ARE, AInputString,
  242.   ATemplate: string): string;
  243. var
  244.   r: TRegExpr;
  245. begin
  246.   r := TRegExpr.Create;
  247.   try
  248.     r.Expression := ARE;
  249.     if r.Exec(AInputString) then
  250.       Result := r.Substitute(ATemplate)
  251.     else
  252.       Result := '';
  253.   finally
  254.     r.Free;
  255.   end;
  256. end;
  257. function TMyThread.IsURL(const AURL: string): Boolean;
  258. var
  259.   URL: string;
  260. begin
  261.   URL := LowerCase(AURL);
  262.   Result := (URL <> '') and
  263.     (URL <> '#') and
  264.     (URL <> '+') and
  265.     (URL <> '') and
  266.     (URL <> 'url;') and
  267.     (URL <> ';') and
  268.     (URL <> 'about:blank') and
  269.     (Pos('.js', URL) = 0) and
  270.     (Pos('.gif', URL) = 0) and
  271.     (Pos('.jpg', URL) = 0) and
  272.     (Pos('.bmp', URL) = 0) and
  273.     (Pos('.swf', URL) = 0) and
  274.     (Pos('.jpeg', URL) = 0) and
  275.     (Pos('.ico', URL) = 0) and
  276.     (Pos('.css', URL) = 0) and
  277.     (Pos('.mp3', URL) = 0) and
  278.     (Pos('.rm', URL) = 0) and
  279.     (Pos('.avi', URL) = 0) and
  280.     (Pos('.mpeg', URL) = 0) and
  281.     (Pos('.pdf', URL) = 0) and
  282.     (Pos('.emf', URL) = 0) and
  283.     (Pos('.pix', AURL) = 0) and
  284.     (Pos('.png', AURL) = 0) and
  285.     (Pos('.wmf', URL) = 0) and
  286.     (Pos('.exe', URL) = 0) and
  287.     (Pos('.rar', URL) = 0) and
  288.     (Pos('.zip', URL) = 0) and
  289.     (Pos('javascript', URL) = 0) and
  290.     (Pos('mailto', URL) = 0);
  291. end;
  292. function TMyThread.ParseString(const ARE, AInputString: string): string;
  293. var
  294.   r: TRegExpr;
  295.   s: string;
  296. begin
  297.   r := TRegExpr.Create;
  298.   try
  299.     r.Expression := ARE;
  300.     if r.Exec(AInputString) then
  301.       repeat
  302.         s := r.Match[1];
  303.         if not IsURL(s) then
  304.           Continue;
  305.         if s[1] = '/' then
  306.           s := ParseString(URLHostRE, FHTTP.URL, '$1') + s
  307.         else if LowerCase(Copy(s, 1, 4)) <> 'http' then
  308.           s := ParseString(URLPathRE, FHTTP.URL, '$1') + s;
  309.         s := StringReplace(s, ',', '^', [rfReplaceAll]);
  310.         //s := StringReplace(s, ' ', '%20', [rfReplaceAll]);
  311.         Result := Result + s + ',';
  312.       until not r.ExecNext;
  313.   finally
  314.     r.Free;
  315.   end;
  316. end;
  317. procedure TMyThread.Terminate;
  318. begin
  319.   inherited Terminate;
  320.   FEvent.SetEvent;
  321.   FHTTP.Abort(False, False);
  322. end;
  323. procedure TForm1.Button1Click(Sender: TObject);
  324. var
  325.   MyThread: TMyThread;
  326.   i: Integer;
  327. begin
  328.   FIndex := 0;
  329.   Memo1.Clear;
  330.   Memo1.Lines.Add(Edit1.Text);
  331.   for i := 0 to SpinEdit1.Value - 1 do
  332.   begin
  333.     MyThread := TMyThread.Create(Edit1.Text);
  334.     FList.Add(MyThread);
  335.     MyThread.Resume;
  336.   end;
  337. end;
  338. procedure TForm1.Button2Click(Sender: TObject);
  339. var
  340.   List: TList;
  341.   i: Integer;
  342. begin
  343.   List := FList.LockList;
  344.   try
  345.     for i := 0 to List.Count - 1 do
  346.       TMyThread(List[i]).Terminate;
  347.   finally
  348.     FList.UnlockList;
  349.   end;
  350. end;
  351. procedure TForm1.Memo1Change(Sender: TObject);
  352. begin
  353.   StatusBar1.Panels[0].Text := Format('%d URLs, Current Index: %d',
  354.     [Memo1.Lines.Count, FIndex]);
  355. end;
  356. procedure TForm1.Edit1Change(Sender: TObject);
  357. begin
  358.   Button1.Enabled := (Sender as TEdit).Text <> '';
  359. end;
  360. procedure TMyThread.AddData;
  361. begin
  362.   Form1.Memo2.Lines.BeginUpdate;
  363.   try
  364.     FData.Text := StringReplace(FData.Text, '#', '@', [rfReplaceAll]);
  365.     //FData.Text := StringReplace(FData.Text,'%20', ' ', [rfReplaceAll]);
  366.     Form1.Memo2.Lines.AddStrings(FData);
  367.     Form1.Memo2.Lines.Delete(Form1.Memo2.Lines.Count - 1);
  368.     Application.ProcessMessages;
  369.   finally
  370.     Form1.Memo2.Lines.EndUpdate;
  371.   end;
  372. end;
  373. procedure TMyThread.AddURLs;
  374. begin
  375.   Form1.Memo1.Lines.BeginUpdate;
  376.   try
  377.     FURLs.Text := StringReplace(FURLs.Text, '^', ',', [rfReplaceAll]);
  378.     FURLs.Text := StringReplace(FURLs.Text, '%20', ' ', [rfReplaceAll]);
  379.     Form1.Memo1.Lines.AddStrings(FURLs);
  380.     Form1.Memo1.Lines.Delete(Form1.Memo1.Lines.Count - 1);
  381.     Application.ProcessMessages;
  382.   finally
  383.     Form1.Memo1.Lines.EndUpdate;
  384.   end;
  385. end;
  386. function TMyThread.ParseEmails(const ARE, AInputString: string): string;
  387. var
  388.   r: TRegExpr;
  389.   s: string;
  390. begin
  391.   r := TRegExpr.Create;
  392.   try
  393.     r.Expression := ARE;
  394.     if r.Exec(AInputString) then
  395.       repeat
  396.         s := r.Match[1];
  397.         s := StringReplace(s, ' ', '%20', [rfReplaceAll]);
  398.         Result := Result + s + ',';
  399.       until not r.ExecNext;
  400.   finally
  401.     r.Free;
  402.   end;
  403. end;
  404. end.