08. august 2006 - 00:01
Der er
6 kommentarer og
1 løsning
WinINet og POST
Ey
Jeg sider og leger med Dephi og WinINet API. Overordnet prøver jeg at lave en mindre crawler. Jeg er dog stødt ind i et problem:
For at "komme videre" på nogen sider skal jeg sende POST data. Hvordan gør jeg det? Jeg har prøvet lidt af hvert men det ser ikke ud til at fungere.
I øjeblikket ser koden således ud:
---------
function TCrawlForm.DownloadFile(DownloadFrom, SaveTo, sPost : string):boolean;
const
BufferSize = 1024;
var
hSession, hURL, hConnection: HInternet;
Buffer: array[1..BufferSize] of Byte;
BufferLen: DWORD;
f: File;
begin
Result := False;
hSession := InternetOpen(PChar(ExtractFileName(Application.ExeName)), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if sPost<>'' then
hConnection := InternetConnect(hSession, PChar('tagdataserver'), INTERNET_DEFAULT_HTTP_PORT, nil, PChar('HTTP/1.0'), INTERNET_SERVICE_HTTP, 0, 0);
try
if sPost<>'' then
begin
hURL := HttpOpenRequest(hConnection,PChar('POST'),PChar(DownloadFrom),PChar('HTTP/1.1'),nil,0,0,0);
HttpSendRequest(hURL, nil, 0, Addr(sPost), Length(sPost));
end
else
hURL := InternetOpenURL(hSession, PChar(DownloadFrom), nil,0,0,0);
try
AssignFile(f, SaveTo);
Rewrite(f,1);
repeat
InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen);
BlockWrite(f, Buffer, BufferLen);
until BufferLen = 0;
CloseFile(f);
Result:=True;
finally
InternetCloseHandle(hURL);
end;
finally
InternetCloseHandle(hSession);
end;
end;
------
Meningen med ovenstående funktion er at sende POST dataen i variablen sPost til serveren (DownloadFrom) og derefter gemme HTML siden i SaveTo.
Alt fungere som det skal men kun når sPost = ''.
Altså er der noget galt med min håndtering af InternetConnect(), HttpOpenRequest() og/eller HttpSendRequest().
Nogen der kan hjælpe?
08. august 2006 - 08:50
#1
Uden nærmere kendskab til HttpSendRequest er der vel noget galt i din linie:
HttpSendRequest(hURL, nil, 0, Addr(sPost), Length(sPost));
sPost bliver ikke overført som pChar
08. august 2006 - 14:00
#2
hmm, ja, det giver lidt mere mening at skrive PChar() i stedet for Addr(), eller nu er jeg hvertfald mere sikker på hvad fanden PChar egentlig er for noget :D.
Men det hjalp dog stadig ikke :/ .
08. august 2006 - 14:35
#3
du må lige lave en nulltermineret streng:
Var SNull: Array[0..255] of char;
flytte indholdet derover
StrPCopy(SNull,sPost);
og så bruge SNull i kaldet. (ikke noget med addr)
mvh Anders
08. august 2006 - 16:00
#4
Nu ser kaldet således ud:
HttpSendRequest(hURL, nil, 0, StrPCopy(SNull,sPost), Length(SPost));
Det fungerede stadig ikke. Jeg tænkte så der måtte være noget med Length(sPost), så jeg har prøvet både med +1 og -1 samt sende længden af SNull med. Ingen gav resultat. Jeg har også prøvet at "rense" SNull (altså sætte alle tegn til #0) inden den får sPost's indhold.
Windows sender False/0/error eller hvad den nu har lyst til at sende tilbage.
btw så var der en af 0'erne i HttpOpenRequest som skulle være en nil, men det fandt Delphi åbenbart selv ud af at lave om.
08. august 2006 - 16:45
#5
Jeg har rodet lidt med noget GetLastError() ect. og den melder følgende fejl (copy+paste fra msdn):
ERROR_INTERNET_NAME_NOT_RESOLVED
12007
The server name could not be resolved.
Så må det vel være i InternetConnect() der er problemmer da anden parameter er "ServerName". Kan jeg mon så bare skrive min egen IP eller kan dette servernavn findes?
... lol jeg lyder som en noob her :D
08. august 2006 - 18:51
#7
OK,
Får næsten lyst til at rode lidt med de der http-kald, men har ikke alt for meget tid :-((
Husk lige at det kan være fælles memory der bruges. Længdeangivelsen fortæller da hvor meget plads du har reserveret. Derfor bedre med ..,sNull,..) og ikke functionkaldet direkte i parameterlisten.
God fornøjelse!