Avatar billede allenb Nybegynder
06. januar 2002 - 16:51 Der er 11 kommentarer og
1 løsning

Hente html source udfra en url...

Er der mon nogen der ligger inde med en kode stump, der kan hente html source udfra en url og så skrive resultatet i en tekst fil???
Det skulle gerne kunne kompileres under windows med Visual C++ 6.0.

Har fundet denne på nettet, men får en del uforståelige fejl under kompilering????

http://www.codeguru.com/internet/GetSourceHtml.html

På forhånd tak for hjælpen og godt nytår!
Avatar billede mbulow Nybegynder
06. januar 2002 - 18:19 #1
Hejsa :)

Jeg har et lille stykke kode (lidt under 200linjer) liggende, hvor man kan indtaste en URL, trykke på \"FETCH\"-knappen, og så henter og viser den sourcen i en RichEdit-control.

Godt nok gemmer den IKKE noget i nogen fil, men det kan være du kan bruge det som en hjælp i den rigtige retning ;)

Koden kommer som en kommentar lige efter dette svar.

VIGTIGT: Når du indtaster en URL, så husk det hele... Altså http://www.eksperten.dk i stedet for www.eksperten.dk, ellers virker det IKKE.
Derudover skal du selv trykke på \"FETCH\"-knappen, det er ikke nok at trykke på retur/enter

PS!!!
Jeg lavede kun projektet for at finde ud af hvordan man kunne hente sourcen fra en URL, og jeg har ikke gået vildt meget op i om der var fejl i koden eller ej (Der er ihvert fald ikke så alvorlige fejl, at det ikke virker)
Så hvis du finder fejl, er de mindst lige så gratis som resten af koden, men du må da meget gerne melde tilbage, hvis du finder en, så jeg kan få rettet den ;) Hehe
Avatar billede mbulow Nybegynder
06. januar 2002 - 18:19 #2
#include <windows.h>
#include <richedit.h>
#include <wininet.h>

BOOL CloseInternetHandle(HINTERNET hInternet);
void DeleteBuffer(char **ppBuffer, unsigned long dwBufferSize);
HINTERNET InitializeInternetFunctions(void);
HINTERNET OpenURL(HINTERNET hInternet, char *szURL);
BOOL ReadURL(HINTERNET hURL, char **ppData, unsigned long *pdwDataSize);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

//Måske nok lidt overkill at lave tre separate funktioner til at kalde
//InternetCloseHandle, InternetOpen og InternetOpenUrl,
//men på denne måde kan fejlhåndteringen (MessageBox ved fejl) fjernes fra den centrale kode
BOOL CloseInternetHandle(HINTERNET hInternet){
BOOL bResult = InternetCloseHandle(hInternet);
if(!bResult)
  MessageBox(NULL, \"Error closing Internet handle\", \"Error: CloseInternetHandle\", MB_ICONERROR);
return bResult;
}
HINTERNET InitializeInternetFunctions(void){
HINTERNET hResult = InternetOpen(\"URL fun\", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(!hResult)
  MessageBox(NULL, \"Error initializing Internet functions\", \"Error: InitializeInternetFunctions\", MB_ICONERROR);
return hResult;
}
HINTERNET OpenURL(HINTERNET hInternet, char *szURL){
HINTERNET hResult = InternetOpenUrl(hInternet, szURL, NULL, 0, 0, 0);
if(!hResult)
  MessageBox(NULL, \"Error opening URL\", \"Error: OpenURL\", MB_ICONERROR);
return hResult;
}

//Dealloker en buffer, og sæt pointeren til NULL
void DeleteBuffer(char **ppBuffer, unsigned long dwBufferSize){
if(*ppBuffer){
  if(dwBufferSize > 1)
  delete [] *ppBuffer;
  else
  delete *ppBuffer;
  *ppBuffer = NULL;
}
}

BOOL ReadURL(HINTERNET hURL, char **ppData, unsigned long *pdwDataSize){
BOOL          bResult;
unsigned long  dwBytesAvailable;
unsigned long  dwBytesRead;
unsigned long  dwResultSize = 0;
char          *pResult = NULL;
char          *pTemp;

while((bResult = InternetQueryDataAvailable(hURL, &dwBytesAvailable, 0, 0)) && dwBytesAvailable){
  pTemp = pResult;
  if(pResult = new char[dwResultSize + dwBytesAvailable]){
  memcpy(pResult, pTemp, dwResultSize);
  InternetReadFile(hURL, pResult + dwResultSize, dwBytesAvailable, &dwBytesRead);
  }
  DeleteBuffer(&pTemp, dwResultSize);
  dwResultSize += dwBytesAvailable;
}
if(bResult){                        //Stoppede while-løkken, fordi alle data er hentet???
  *ppData = pResult;
  *pdwDataSize = dwResultSize;
}else{                            // Eller fordi der er sket en fejl???
  MessageBox(NULL, \"Error reading URL\", \"Error: ReadURL\", MB_ICONERROR);
  DeleteBuffer(&pResult, dwResultSize);
}
return bResult;
}

//1) Alloker ny buffer med plads til et afsluttende \'\\0\'
//2) Vis teksten i hWnd
//3) Slet den nye buffer
void ShowData(HWND hWnd, char *pData, unsigned long dwDataSize){
char *pTemp;

if(hWnd && pData && dwDataSize && (pTemp = new char[dwDataSize+1])){
  memcpy(pTemp, pData, dwDataSize);
  pTemp[dwDataSize] = \'\\0\';
  SetWindowText(hWnd, pTemp);
  DeleteBuffer(&pTemp, dwDataSize + 1);
}
else
  MessageBox(NULL, \"Error showing the data\", \"Error: ShowData\", MB_ICONERROR);
}

//Ikke andet end en standard WinMain der opretter et vindue,
//og starter message loopet
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){
HWND    hWnd;
MSG      msg;
TCHAR    szClassName[] = \"URLfun\";
WNDCLASS WndClass;

WndClass.cbClsExtra    = 0;
WndClass.cbWndExtra    = 0;
WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
WndClass.hCursor    = LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon        = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hInstance    = hInstance;
WndClass.lpfnWndProc  = WindowProc;
WndClass.lpszClassName = szClassName;
WndClass.lpszMenuName  = NULL;
WndClass.style        = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

if(!RegisterClass(&WndClass)){
  MessageBox(NULL, \"Error registering the window class\", \"Error: RegisterClass\", MB_ICONERROR);
  return 0;
}

hWnd = CreateWindow(szClassName, \"URL fun\", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

ShowWindow(hWnd, nShowCmd);
UpdateWindow(hWnd);

while(GetMessage(&msg, NULL, 0, 0)){
  TranslateMessage(&msg);
  DispatchMessage(&msg);
}

return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
static unsigned long  dwBufferSize;
static HWND          hFetchButton;
static HINSTANCE      hInstance;
static HINTERNET      hInternet;
static HWND          hMainWnd;
static HINSTANCE      hRichEditLib;
static HWND          hRichEditWnd;
static HINTERNET      hURL;
static HWND          hURLWnd;
static int            iURLLength;
static char          *pBuffer;
static RECT          rect;
static char          *szURL;

switch(uMsg){
  case WM_COMMAND:
  if(HIWORD(wParam) == BN_CLICKED){
    if((iURLLength = GetWindowTextLength(hURLWnd)) && (szURL = new char[iURLLength+1])){
    if((GetWindowText(hURLWnd, szURL, iURLLength+1) == iURLLength) && (hURL = OpenURL(hInternet, szURL))){
      ReadURL(hURL, &pBuffer, &dwBufferSize);
      CloseInternetHandle(hURL);
    }
    delete [] szURL;
    szURL = NULL;
    }
    if(pBuffer){
    ShowData(hRichEditWnd, pBuffer, dwBufferSize);
    DeleteBuffer(&pBuffer, dwBufferSize);
    }
    else
    SetWindowText(hRichEditWnd, \"\");
  }
  return 0;
  case WM_CREATE:
  dwBufferSize = 0;
  hInternet = hURL = pBuffer = NULL;
  hMainWnd = hWnd;
  GetClientRect(hMainWnd, &rect);
  hRichEditLib = LoadLibrary(\"riched20.dll\");
  hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
  hURLWnd = CreateWindow(\"EDIT\", \"Enter a valid URL (http://www.eksperten.dk) and click the Fetch button\",
                          WS_BORDER | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT, 0, 0,
                          rect.right - 60, 20, hMainWnd, NULL, hInstance, NULL);
  hFetchButton = CreateWindow(\"BUTTON\", \"Fetch\", WS_CHILD | WS_VISIBLE, rect.right - 60, 0, 60, 20,
                              hMainWnd, NULL, hInstance, NULL);
  hRichEditWnd = CreateWindow(RICHEDIT_CLASS, NULL,
                              WS_CHILD | WS_HSCROLL | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE,
                              0, 20, rect.right, rect.bottom - 20, hMainWnd, NULL, hInstance, NULL);
  hInternet = InitializeInternetFunctions();
  break;
  case WM_DESTROY:
  if(hInternet)    CloseInternetHandle(hInternet);
  if(hRichEditWnd) DestroyWindow(hRichEditWnd);
  if(hFetchButton) DestroyWindow(hFetchButton);
  if(hURLWnd)      DestroyWindow(hURLWnd);
  FreeLibrary(hRichEditLib);
  PostQuitMessage(0);
  return 0;
}

return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Avatar billede mbulow Nybegynder
06. januar 2002 - 18:20 #3
Damn!!! Nu har jeg igen fået lavet lettere rod i formateringen :/ Sorry about that :)
Avatar billede mbulow Nybegynder
06. januar 2002 - 23:00 #4
Hej igen :)

Jeg har lavet en ny version, af den kode jeg gav dig tidligere... Denne gang vises kilden IKKE i et vindue, men du indtaster et filnavn, og så bliver den gemt direkte til filen.

Hvis jeg lige kort skal summere hvad jeg gør (Uden alt GUI-koden), så er det følgende:

1) I WM_CREATE (i WindowProc-funktionen), kalder jeg InitializeInternetFunctions()
2) Brugeren indtaster URL, Filnavn og trykker på FETCH
I WM_COMMAND:
  3) Aflæser URL\'en
  4) Åbner forbindelse til URL\'en
  5) Aflæser Filnavnet
  6) Kalder StoreURLSource-funktionen (Det er der det vigtige sker ;)
  7) Lukker forbindelsen til URL\'en
Når du lukker applikationen (i WM_DESTROY)
  8) Et afsluttende kald til CloseInternetHandle()

Jeg håber det giver lidt overblik over hvad det er GUI, og hvad der er funktionalitet :)

Koden kommer i næste kommentar
Avatar billede mbulow Nybegynder
06. januar 2002 - 23:01 #5
#include <windows.h>
#include <wininet.h>
#include <fstream>

using namespace std;

BOOL CloseInternetHandle(HINTERNET hInternet){
    BOOL bResult;
    bResult = InternetCloseHandle(hInternet);
    if(!bResult)
        MessageBox(NULL, \"Error closing Internet handle\", \"Error: CloseInternetHandle\", MB_ICONERROR);
    return bResult;
}
HINTERNET InitializeInternetFunctions(void){
    HINTERNET hResult;
    hResult = InternetOpen(\"URL fun\", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if(!hResult)
        MessageBox(NULL, \"Error initializing Internet functions\", \"Error: InitializeInternetFunctions\", MB_ICONERROR);
    return hResult;
}
HINTERNET OpenURL(HINTERNET hInternet, char *szURL){
    HINTERNET hResult;
    hResult = InternetOpenUrl(hInternet, szURL, NULL, 0, 0, 0);
    if(!hResult)
        MessageBox(NULL, \"Error opening URL\", \"Error: OpenURL\", MB_ICONERROR);
    return hResult;
}

void DeleteBuffer(char **ppBuffer, unsigned long dwBufferSize){
    if(*ppBuffer){
        if(dwBufferSize > 1)
            delete [] *ppBuffer;
        else
            delete *ppBuffer;
        *ppBuffer = NULL;
    }
}

char *GetLocationText(HWND hWnd){
    int        iLength;
    char    *szText;

    if((iLength = GetWindowTextLength(hWnd)) && (szText = new char[iLength+1])){
        if(GetWindowText(hWnd, szText, iLength+1) == iLength)
            return szText;
        delete [] szText;
    }

    return NULL;
}

bool StoreURLSource(HINTERNET hURL, char *szFileName){
    bool            bResult;
    unsigned long    dwBufferSize;
    unsigned long    dwBytesAvailable;
    unsigned long    dwBytesRead;
    ofstream        outputFile(szFileName);
    char            *pBuffer;

    dwBufferSize = 0;
    pBuffer = NULL;

    while((bResult = InternetQueryDataAvailable(hURL, &dwBytesAvailable, 0, 0)) && dwBytesAvailable){
        if(dwBufferSize < dwBytesAvailable){
            DeleteBuffer(&pBuffer, dwBufferSize);
            dwBufferSize = dwBytesAvailable;
            pBuffer = new char[dwBufferSize];
        }
        InternetReadFile(hURL, pBuffer, dwBytesAvailable, &dwBytesRead);
        outputFile.write(pBuffer, dwBytesAvailable);
    }

    DeleteBuffer(&pBuffer, dwBufferSize);

    return bResult;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
    static HWND                hFetchButton;
    static HWND                hFilenameWnd;
    static HINSTANCE        hInstance;
    static HINTERNET        hInternet;
    static HWND                hMainWnd;
    static HINTERNET        hURL;
    static HWND                hURLWnd;
    static RECT                rect;
    static char                *szFilename;
    static char                *szURL;

    switch(uMsg){
        case WM_COMMAND:
            if(HIWORD(wParam) == BN_CLICKED)
                if(szURL = GetLocationText(hURLWnd)){
                    if(hURL = OpenURL(hInternet, szURL)){
                        if(szFilename = GetLocationText(hFilenameWnd)){
                            if(StoreURLSource(hURL, szFilename))
                                MessageBox(NULL, \"Source saved\", \"Woohoo\", MB_OK);
                            else
                                MessageBox(NULL, \"Source NOT saved\", \"Error\", MB_ICONERROR);
                            delete [] szFilename;
                        }
                        CloseInternetHandle(hURL);
                    }
                    delete [] szURL;
                }
            return 0;
        case WM_CREATE:
            hMainWnd = hWnd;
            GetClientRect(hMainWnd, &rect);
            hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
            hURLWnd = CreateWindow(\"EDIT\", \"1) Valid URL (http://www.eksperten.dk)\", WS_BORDER | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT, 0, 0, rect.right - 60, 20, hMainWnd, NULL, hInstance, NULL);
            hFilenameWnd = CreateWindow(\"EDIT\", \"2) Valid Filename (C:\\\\URLSource.txt)\", WS_BORDER | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT, 0, 20, rect.right - 60, 20, hMainWnd, NULL, hInstance, NULL);
            hFetchButton = CreateWindow(\"BUTTON\", \"3) Fetch\", WS_CHILD | WS_VISIBLE, rect.right - 60, 0, 60, 40, hMainWnd, NULL, hInstance, NULL);
            hInternet = InitializeInternetFunctions();
            break;
        case WM_DESTROY:
            if(hInternet)
                CloseInternetHandle(hInternet);
            if(hFetchButton)
                DestroyWindow(hFetchButton);
            if(hFilenameWnd)
                DestroyWindow(hFilenameWnd);
            if(hURLWnd)
                DestroyWindow(hURLWnd);
            PostQuitMessage(0);
            return 0;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){
    HWND    hWnd;
    MSG        msg;
    TCHAR    szClassName[] = \"URLfun\";
    WNDCLASS WndClass;

    WndClass.cbClsExtra      = 0;
    WndClass.cbWndExtra      = 0;
    WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    WndClass.hCursor      = LoadCursor(NULL, IDC_ARROW);
    WndClass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hInstance      = hInstance;
    WndClass.lpfnWndProc  = WindowProc;
    WndClass.lpszClassName = szClassName;
    WndClass.lpszMenuName  = NULL;
    WndClass.style          = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

    if(!RegisterClass(&WndClass)){
        MessageBox(NULL, \"Error registering the window class\", \"Error: RegisterClass\", MB_ICONERROR);
        return 0;
    }

    hWnd = CreateWindow(szClassName, \"URL fun\", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 40, NULL, NULL, hInstance, NULL);
    ShowWindow(hWnd, nShowCmd);
    UpdateWindow(hWnd);

    while(GetMessage(&msg, NULL, 0, 0)){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}
Avatar billede kamikaze Nybegynder
06. januar 2002 - 23:35 #6
mbulow >> Undskyld hvis jeg blander mig (det er jo ikke mit spørgsmål), men kan du ikke lige sige hvilke .libs der skal linkes til osv. osv. :-)
Avatar billede mbulow Nybegynder
07. januar 2002 - 00:13 #7
Hej kamikaze :)

Du har selvfølgelig helt ret. Jeg havde fuldstændig glemt, at man skal linke til: wininet.lib
(Gammel projekt. Ikke rørt det længe :)

Men ellers skulle der ikke være noget ud over det sædvanlige, bare husk at det skal laves som et \"Win32 Application\", med wininet.lib, hvis det skal virke med ren copy/paste (Har lige prøvet)

Tak for påmindelsen :)
Avatar billede jpk Nybegynder
07. januar 2002 - 09:07 #8
-> allenb: Hvilke linkerfejl får du ved brug af http://www.codeguru.com/internet/GetSourceHtml.html ?

Avatar billede gunzales Nybegynder
13. januar 2002 - 15:06 #9
Hej!

allenb er midlertidig Gunzales, da jeg pludselig ikke kan logge ind med allenb...????
->jpk hvis jeg kopierer fra http://www.codeguru.com/internet/GetSourceHtml.html for og inkl. de to header filer som de beskriver for jeg en fejl: windows.h already included. MFC apps must not include windows.h
->mbulow hvordan implementeres funktionen i et andet program, kan ikke ikke rigtig få det til at køre.
Avatar billede mbulow Nybegynder
13. januar 2002 - 15:30 #10
Hmm... Kan du få det til at køre i et selvstændigt program uden at lave noget om???
Hvis ikke, så gik mig din e-mail, så sender jeg hele projektet



Du skal ha\' følgende funktioner med over i dit \'andet\' program:
---------------------------------------------------------------
BOOL CloseInternetHandle(HINTERNET hInternet)
HINTERNET InitializeInternetFunctions(void)
HINTERNET OpenURL(HINTERNET hInternet, char *szURL)
void DeleteBuffer(char **ppBuffer, unsigned long dwBufferSize)
bool StoreURLSource(HINTERNET hURL, char *szFileName)



Du skal gøre følgende:
----------------------
1) Kald InitializeInternetFunctions() før du bruger nogle af de andre funktioner. Husk at gemme det HINTERNET handle der bliver returneret (hInternet)

2) Kald funktionen OpenURL(hInternet, \"http://www.eksperten.dk/\"), og gem ligesom før det returnerede HINTERNET handle (hURL)

3) Kald funktionen StoreURLSource(hURL, \"C:\\\\Source.txt\"), for at gemme sourcen til en fil (Funktionen returnerer true/false som eneste fejlmelding)

4) Så mangler du bare at lukke de to oprettede (returnerede) HINTERNET-handles (hInternet og hURL)... Så kald CloseInternetHandle(hURL), CloseInternetHandle(hInternet)



Opsummering (Uden fejlhåndtering):
---------------------------------
//Hvis vi er så heldige at vi ikke render ind i en fejl
//skulle følgende fem linjer være nok til at gemme http://www.eksperten.dk sourcen
//i filen c:\\source.txt
//(PS!!! Det ER testet, til at skulle virke)
HINTERNET hInternet = InitializeInternetFunctions();
HINTERNET hURL = OpenURL(hInternet, \"http://www.eksperten.dk/\");
StoreURLSource(hURL, \"C:\\\\Source.txt\");
CloseInternetHandle(hURL);
CloseInternetHandle(hInternet);



PS!!! Husk nu selvfølgelig at linke til wininet.lib  :) Hehe
(Bare hvis du nu havde overset de par indlæg)



Kan du stadig ikke få det til at virke? Har du så mulighed for at poste noget af den kode hvor du skal bruge funktionaliteten? Eller evt. maile den til mig, hvis ikke du vil ha\' det på et åbent forum
Avatar billede gunzales Nybegynder
13. januar 2002 - 17:06 #11
Hejsa!

Det virker nu, det er intet mindre end verdensklasse.....tusind tak!!!!

Jeg skal nok sørge for at du får dine point, skal bare lige ha\' adgang til allenb profilen.

Endnu en gang tusind tak for hjælpen!!!!!!
Avatar billede allenb Nybegynder
06. marts 2002 - 10:21 #12
Så skulle pointene være overført - tak for hjælpen
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester