在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
从扬帆Blog看到的一段代码,整理了一下,留着备用。 原文:http://www.wesoho.com/article/Delphi/2910.htm
unit UDownloadHTML; interface uses SysUtils, Windows, Forms, WinSock, WinInet; function DownloadWithInet(const AUrl: string): string; function DownloadWithSocket(const AUrl: string): string; implementation function DownloadWithInet(const AUrl: string): string; procedure Add(Buf: PChar; Count: Integer); var Len: Integer; begin Len := Length(Result); SetLength(Result, Len + Count); Move(Buf^, Result[Len + 1], Count); end; function PrepareURL: string; begin Result := UpperCase(Copy(AUrl, 1, 7)); if Result <> 'HTTP://' then Result := 'http://' + AUrl else Result := AUrl; end; var BytesRead: DWORD; Session, Connection: HINTERNET; Buffer: array[1..1024] of Char; begin Result := ''; if AUrl = '' then Exit; Session := InternetOpen(nil, INTERNET_OPEN_TYPE_DIRECT, nil, nil, 0); if not Assigned(Session) then raise Exception.Create(SysErrorMessage(GetLastError)); try Connection := InternetOpenUrl(Session, PChar(PrepareURL), nil, 0, INTERNET_FLAG_RAW_DATA, {INTERNET_FLAG_RELOAD, }0); if not Assigned(Connection) then raise Exception.Create(SysErrorMessage(GetLastError)); try repeat FillChar(Buffer, SizeOf(Buffer), 0); InternetReadFile(Connection, @Buffer, SizeOf(Buffer), BytesRead); if BytesRead > 0 then Add(@Buffer, BytesRead); Application.ProcessMessages; until BytesRead = 0; finally InternetCloseHandle(Connection); end; finally InternetCloseHandle(Session); end; end; function DownloadWithSocket(const AUrl: string): string; const CRLF = #13#10; SFileContentLen = 'content-length: '; SUserAgent = 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)'; SRequestFileHead = 'HEAD %s HTTP/1.1' + CRLF + 'Pragma: no-cache' + CRLF + 'Cache-Control: no-cache' + CRLF + SUserAgent + CRLF + 'Host: %s' + CRLF + CRLF; SRequestDownFile = 'GET %s HTTP/1.1' + CRLF + 'Accept: */*' + CRLF + SUserAgent + CRLF + 'RANGE: bytes=0-' + CRLF + 'Host: %s' + CRLF + CRLF; procedure ExtractHostAndFileName(const AURL: string; var AHost, AFileName: string; APort: PString = nil); const HttpHead = 'http://'; HttpHeadLen = Length(HttpHead); var I: Integer; begin AHost := AURL; I := Pos(HttpHead, AURL); if I <> 0 then AHost := Copy(AHost, I + HttpHeadLen, MaxInt); I := AnsiPos('/', AHost); while I <> 0 do begin AHost := Copy(AHost, 1, I - 1); I := AnsiPos('/', AHost); end; I := Pos(AHost, AURL) + Length(AHost); AFileName := Copy(AURL, i, MaxInt); I := Pos(':', AHost); if I <> 0 then begin if Assigned(APort) then APort^ := Copy(AHost, I + 1, MaxInt); AHost := Copy(AHost, 1, I - 1); end; end; var Socket: TSocket; function WaitForSocket(Timeout: Integer): Boolean; var FDSet: TFDSet; TimeVal: TTimeVal; begin TimeVal.tv_sec := Timeout; TimeVal.tv_usec := 0; FD_ZERO(FDSet); FD_SET(Socket, FDSet); Result := WinSock.select(0, @FDSet, nil, nil, @TimeVal) > 0; end; procedure Add(var S: string; Buf: PChar; Count: Integer); var Len: Integer; begin Len := Length(S); SetLength(S, Len + Count); Move(Buf^, S[Len + 1], Count); end; function ReceiveLine: string; var C: Char; RetLen: Integer; begin Result := ''; while Socket <> INVALID_SOCKET do begin RetLen := recv(Socket, C, 1, 0); if (RetLen <= 0) or (RetLen = SOCKET_ERROR) then break; Add(Result, @C, 1); if Pos(CRLF, Result) > 0 then break; end; end; function SendCommand(const Command: string): string; var P: PChar; Data: string; begin Result := ''; P := PChar(Command); send(Socket, P^, Length(Command), 0); while WaitForSocket(5) do begin Data := ReceiveLine; if (Data = '') or (Data = CRLF) then break else Add(Result, PChar(Data), Length(Data)); end; end; procedure InitSocket(const AHost: string); var Addr: TSockAddrIn; Data: TWSAData; HostEnt: PHostEnt; Timeout: Integer; begin Winsock.WSAStartup($0101, Data); Socket := WinSock.socket(PF_INET, SOCK_STREAM, IPPROTO_IP); if Socket = INVALID_SOCKET then raise Exception.Create(SysErrorMessage(GetLastError)); Timeout := 1000; WinSock.setsockopt(Socket, SOL_SOCKET, SO_RCVTIMEO, @Timeout, SizeOf(TimeOut)); HostEnt := gethostbyname(PChar(AHost)); FillChar(Addr.sin_addr, SizeOf(Addr.sin_addr), 0); Addr.sin_family := PF_INET; if HostEnt <> nil then Move(HostEnt^.h_addr^[0], Addr.sin_addr.S_addr, HostEnt^.h_length) else raise Exception.CreateFmt('主机没找到: %s', [AHost]); Addr.sin_port := htons(80); if connect(Socket, Addr, SizeOf(Addr)) <> 0 then raise Exception.Create(SysErrorMessage(GetLastError)); end; procedure UnInitSocket; begin if Socket <> INVALID_SOCKET then closesocket(Socket); WSACleanup; end; var Data, FileName, Host: string; begin Socket := INVALID_SOCKET; ExtractHostAndFileName(AUrl, Host, FileName); try InitSocket(Host); if FileName = '' then FileName := '/'; Data := SendCommand(Format(SRequestFileHead, [FileName, Host])); Data := SendCommand(Format(SRequestDownFile, [FileName, Host])); while True do begin Data := ReceiveLine; if Data = '' then break; Add(Result, PChar(Data), Length(Data)); Application.ProcessMessages; end; finally UnInitSocket; end; end; end.
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论