View Full Version : [c] aprire un sito internet
mi kiedevo se cé la posbbilità con un comando aprire un sito internet, ad es:
system("www.smipweb");
cosi nn funziona, anche mettendo http:
come posso fare?
grazie
mi kiedevo se cé la posbbilità con un comando aprire un sito internet, ad es:
system("www.smipweb");
cosi nn funziona, anche mettendo http:
come posso fare?
grazieSu Windows puoi usare la funzione Win32 ShellExecute().
#include <windows.h>
...
ShellExecute (NULL, "open", "http://www.google.com", NULL, NULL, SW_SHOW);
grande!!! cé un modo per salvare la pagina? xké in mozzila nn credo vengano salvate tutte le pag web
grande!!! cé un modo per salvare la pagina? xké in mozzila nn credo vengano salvate tutte le pag webFammi capire: vuoi fare un qualcosa che scarichi in locale una pagina web? (e in questo caso il browser non centra nulla).
Devi usare delle librerie esterne o altri tool, come ad esempio il ben noto "wget".
ma wget é un programma? xké nn si puo fare tutto in C? xké appunto vorrei ke ogni giorno aprendo il programma in C mi salvi una determinata pag web
Prova usando i socket, devi connetterti al server, poi da li dai una GET per avere la pagina
eh mi sa ke nn sono cosi avanti con c:D xké nn so cosa sono i socket....puoi farmi un es?
che sistema usi, windows o linux?
dai uno sguardo qui
get_page(){
char *url= "qui inserisci l'indirizzo del server";
char id[3];
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char sendbuf[1024];
char *get="GET ";
char *pagina="/pagina.html";
char *closer=" HTTP/1.0\n";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN-1;
char *working;
FILE * temp;
//genero la richiesta
sendbuf[0]=0;
strcat(sendbuf,get);
strcat(sendbuf,pagina);
strcat(sendbuf,closer);
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
exit(0);
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(url, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
exit(0);
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
exit(0);
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
exit(0);
}
// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
exit(0);
}
printf("Dati richiesti al server");
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
exit(0);
}
// Receive until the peer closes the connection and puts data to temp file
temp = fopen("file.html","w");
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 ){
recvbuf[iResult]=0;
fprintf(temp,"%s", recvbuf);
printf(".");
}
else if ( iResult == 0 )
printf("\nDati ottenuti\n");
else
printf("recv failed: %d\n", WSAGetLastError());
} while( iResult > 0 );
// cleanup
closesocket(ConnectSocket);
WSACleanup();
fclose(temp);
return 0;
}
nota, per compilare devi includere
#include <winsock2.h>
#include <ws2tcpip.h>
e linkare la libreria WS2_32.lib
In pratica se voglio ottenere la pagina www.sito.com/pagina.html mi connetto al server www.sito.com, invio il messaggio
"GET /pagina.html HTTP/1.0\n", e poi mi metto in ascolto per ottenere la pagina che verrà salvata nel file temp.html
nota che questo codice preleva solo l'html, se vuoi anche immagini o altro il procedimento è lo stesso
ma wget é un programma?Sì, è un programma.
xké nn si puo fare tutto in C?Il "C" non ha funzioni "standard" per la gestione dei protocolli HTTP, FTP, ecc....
Bisogna usare librerie di terze parti o eventuali librerie di sistema.
Puoi usare i socket per fare una connessione HTTP ma .... è palloso.
Su Windows puoi usare le API WinINet. Ecco un esempio.
#define STRICT
#include <windows.h>
#include <wininet.h>
BOOL DownloadFromURL (LPSTR lpszUrl, LPSTR lpszFilename)
{
HINTERNET hInternet;
HINTERNET hInternetUrl;
HANDLE hFile;
BYTE bBuffer[1024];
DWORD dwRead;
DWORD dwWritten;
BOOL bRet = FALSE;
hInternet = InternetOpen ("MyAgent/1.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (hInternet != NULL)
{
hInternetUrl = InternetOpenUrl (hInternet, lpszUrl, NULL, 0, 0, 0);
if (hInternetUrl != NULL)
{
hFile = CreateFile (lpszFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
do {
bRet = InternetReadFile (hInternetUrl, bBuffer, sizeof (bBuffer), &dwRead);
if (bRet && dwRead > 0)
{
bRet = WriteFile (hFile, bBuffer, dwRead, &dwWritten, NULL);
if (bRet && dwWritten != dwRead)
bRet = FALSE;
}
} while (bRet && dwRead == sizeof (bBuffer));
CloseHandle (hFile);
}
InternetCloseHandle (hInternetUrl);
}
InternetCloseHandle (hInternet);
}
return bRet;
}
int main (int argc, char *argv[])
{
BOOL bRet;
bRet = DownloadFromURL ("http://www.google.com", "C:\\TEMP\\google.html");
return 0;
}
Nota solo 2 cose importanti:
- Bisogna linkare con la libreria wininet.lib
- Come stringa di identificazione dello user-agent ho usato "MyAgent/1.0". Se il sito è dinamico (PHP, ASP, ecc...), la pagina mandata in output potrebbe variare a seconda dello user-agent.
Sì, è un programma.
Il "C" non ha funzioni "standard" per la gestione dei protocolli HTTP, FTP, ecc....
Bisogna usare librerie di terze parti o eventuali librerie di sistema.
Puoi usare i socket per fare una connessione HTTP ma .... è palloso.
Su Windows puoi usare le API WinINet. Ecco un esempio.
#define STRICT
#include <windows.h>
#include <wininet.h>
BOOL DownloadFromURL (LPSTR lpszUrl, LPSTR lpszFilename)
{
HINTERNET hInternet;
HINTERNET hInternetUrl;
HANDLE hFile;
BYTE bBuffer[1024];
DWORD dwRead;
DWORD dwWritten;
BOOL bRet = FALSE;
hInternet = InternetOpen ("MyAgent/1.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (hInternet != NULL)
{
hInternetUrl = InternetOpenUrl (hInternet, lpszUrl, NULL, 0, 0, 0);
if (hInternetUrl != NULL)
{
hFile = CreateFile (lpszFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
do {
bRet = InternetReadFile (hInternetUrl, bBuffer, sizeof (bBuffer), &dwRead);
if (bRet && dwRead > 0)
{
bRet = WriteFile (hFile, bBuffer, dwRead, &dwWritten, NULL);
if (bRet && dwWritten != dwRead)
bRet = FALSE;
}
} while (bRet && dwRead == sizeof (bBuffer));
CloseHandle (hFile);
}
InternetCloseHandle (hInternetUrl);
}
InternetCloseHandle (hInternet);
}
return bRet;
}
int main (int argc, char *argv[])
{
BOOL bRet;
bRet = DownloadFromURL ("http://www.google.com", "C:\\TEMP\\google.html");
return 0;
}
Nota solo 2 cose importanti:
- Bisogna linkare con la libreria wininet.lib
- Come stringa di identificazione dello user-agent ho usato "MyAgent/1.0". Se il sito è dinamico (PHP, ASP, ecc...), la pagina mandata in output potrebbe variare a seconda dello user-agent.
In effetti così è molto più comodo...
m...nn funziona! mi da deji errori su dei link!!
m...nn funziona! mi da deji errori su dei link!!
Puoi spiegare meglio il tuo problema, l'errore è in compilazione o a run-time?
Puoi spiegare meglio il tuo problema, l'errore è in compilazione o a run-time?Credo che il problema ce l'abbia in fase di link. Mi sembra di ricordare che lui usa il Dev-C++. Se così, deve linkare con libwininet.a!
si uso dev-c++....ma per linkarlo devo fare #include <libwininet.a>? xké nn me lo trova, e in internet non riesco a trovarlo...
si uso dev-c++....ma per linkarlo devo fare #include <libwininet.a>?Ma no!
Se usi un ambiente di sviluppo, sforzati un pochino di capire come funziona!
Vai nelle proprietà del progetto e lì ci trovi un campo apposito in cui puoi inserire i nomi degli oggetti (o librerie) da passare al linker!
mi da cmq errore: [Build error] [esempio2.exe] Error1
boh!!! io ho linkato,e infatti nn mi da gli errori ke mi dava prima......xo nn funziona!! non capisco.....
mi da cmq errore: [Build error] [esempio2.exe] Error1
boh!!! io ho linkato,e infatti nn mi da gli errori ke mi dava prima......xo nn funziona!! non capisco.....Guarda ... io il Dev-C++ non lo uso normalmente (lo uso solo per prove come in questo caso).
Il sorgente che ho postato sono riuscito a compilarlo/linkarlo ... però:
a) Ho dovuto specificare nelle proprietà del progetto il path completo della libwininet.a, altrimenti mi dà errore. A fianco della casella dove mettere gli oggetti, c'è un pulsante "Load object files" e ho selezionato il file con quello.
Cosa comunque strana, visto che la \Lib del Dev-C++ è già configurata nelle opzioni.
b) Una volta ottenuto l'eseguibile, comunque non funziona. Sembra che l'eseguibile non abbia il corretto collegamento con la WININET.DLL. Presumo (ma non ne sono sicuro) che la libwininet.a del Dev-C++ sia "fallata" o non aggiornata.
Ti consiglio vivamente di usare un altro IDE/compilatore. Esempio: Visual C++ 2005 Express oppure il BCC 5.5 a linea di comando (ma ti devi "sporcare" un po' le mani con i Makefile).
infatti nn riesco a compilarlo....mi da sempre errore. Xcio ho provato a installare il visual c++, ma ho difficoltà nel compilare: ho fatto un nuovo progetto ma poi quando faccio il debug, é un po un casino,e nn me lo compila....bah, ma in devc++ non é quindi possibile? magari in altro modo, usando i socket ad es come diceva wisher (ho provato a compilare il suo di codice e non funziona).
infatti nn riesco a compilarlo....mi da sempre errore. Xcio ho provato a installare il visual c++, ma ho difficoltà nel compilare: ho fatto un nuovo progetto ma poi quando faccio il debug, é un po un casino,e nn me lo compila....bah, ma in devc++ non é quindi possibile? magari in altro modo, usando i socket ad es come diceva wisher (ho provato a compilare il suo di codice e non funziona).
mi pare che visual studio express nn abbia tutte le librerie che però sono scaricabili a parte, adesso cerco il link...
qui ci sono le platform SDK, dovrebbe contenere tutto l'occorrente
http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/
per fare il linking in visual studio vai in Progetto->proprietà progetto, scegli linker e in input aggiungi wininet.lib alla voce dipendenze aggiuntive
Più semplicemente, usa wget come tool esternamente, richiamandola con una classica system call "execve" di C, o se voi fare ancora più il figo, fai una fork() (o un thread in windows) e nel processo/thread risultante fai la execve: in questo modo scarichi la pagina internet SENZA che il tuo programma attenda la terminazione di wget, quindi il processo prinicpale continua a fare altro.
Se poi vuoi proprio usare i socket o librerie non portabili di windows, sarai accontentato :D Vedo che già sono state postete un paio di soluzioni "in code" :)
EDIT: se vuoi usare socket o librerie di più altro livello, ti conviene leggrti un po' i meccanismi client-server, cosa sono i socket, ecc., sennò rischi di copiare "bovinamente" del codice senza capirci nulla, e questo per un programmatore è da evitare.
Su Windows puoi usare la funzione Win32 ShellExecute().
#include <windows.h>
...
ShellExecute (NULL, "open", "http://www.google.com", NULL, NULL, SW_SHOW);
non è portabile... meglio una classica execXXX, che lancia prima firefox, in mancanza di questo prova Opera, poi IE (il tutto per garantire portabilità). Ma comunque vedo che non era questo il suo obiettivo...
non è portabile... meglio una classica execXXX, che lancia prima firefox, in mancanza di questo prova Opera, poi IE (il tutto per garantire portabilità). Ma comunque vedo che non era questo il suo obiettivo...Ma LOL!! Primo: all'inizio $te chiedeva come "aprire un sito internet" ed io ... ho indicato ShellExecute. Secondo: ovvio che non è portabile!!! È una API Win32. Se per questo nemmeno l'utilizzo della libreria WinINet è "portabile".
Ma LOL!! Primo: all'inizio $te chiedeva come "aprire un sito internet" ed io ... ho indicato ShellExecute. Secondo: ovvio che non è portabile!!! È una API Win32. Se per questo nemmeno l'utilizzo della libreria WinINet è "portabile".
Non volevo mica fare polemica... facevo solo notare che è normalmente consigliabile appoggiarsi alle system call che a funzioni di libreria propietarie, quando ciò è possibile.
Stesso discorso per WinINet: preferisco i socket bsd (implementati in Windows con pochissime differenze), o e vuoi maggiore "trasparenza" ci sono in giro diverse librerie che "nascondono" i socket, che presentano i relativi wrapper di compatibilità con altre piattaforme. A mio parere è buona prassi, tutto qui :)
NB: non sono riuscito ancora a capire cosa si intende con LOL! ;)
fidel fammi capire un attimo. ho cercato un po in rete ke é wget....ed é programma x scaricare (non ho ancora trovato il tempo x scaricarlo), quindi in pratica apro il programma wget? (system("wget.exe")?) in questo modo significa ke wget dovrebbe aprirsi e poi automaticamente scaricare un pag web e salvarla,xo poi nn si kiuderebbe da solo; ho guardato un po per la funzione fork(): a quanto ho capito consente d avviare due processi in simultanea juso? ho provato sto semplice codice:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
fork(); //duplicazione del processo
printf("Sono il padre\n");
printf("sono il figlio\n");
return EXIT_SUCCESS;
}
xo mi da errore: mi dice ke fork non é dikiarata!!! come mai?
fidel fammi capire un attimo. ho cercato un po in rete ke é wget....ed é programma x scaricare (non ho ancora trovato il tempo x scaricarlo), quindi in pratica apro il programma wget? (system("wget.exe")?) in questo modo significa ke wget dovrebbe aprirsi e poi automaticamente scaricare un pag web e salvarla,xo poi nn si kiuderebbe da solo; ho guardato un po per la funzione fork(): a quanto ho capito consente d avviare due processi in simultanea juso? ho provato sto semplice codice:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
fork(); //duplicazione del processo
printf("Sono il padre\n");
printf("sono il figlio\n");
return EXIT_SUCCESS;
}
xo mi da errore: mi dice ke fork non é dikiarata!!! come mai?
fork è solo su linux...
fidel fammi capire un attimo. ho cercato un po in rete ke é wget....ed é programma x scaricare (non ho ancora trovato il tempo x scaricarlo), quindi in pratica apro il programma wget? (system("wget.exe")?) in questo modo significa ke wget dovrebbe aprirsi e poi automaticamente scaricare un pag web e salvarla,xo poi nn si kiuderebbe da solo;Sì, ovviamente devi passare dei parametri a wget.
Esempio:
system("wget http://www.google.com -O google.html");
ho guardato un po per la funzione fork(): a quanto ho capito consente d avviare due processi in simultanea juso? ho provato sto semplice codice:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
fork(); //duplicazione del processo
printf("Sono il padre\n");
printf("sono il figlio\n");
return EXIT_SUCCESS;
}Il concetto di "fork" è una cosa che esiste nativamente solo nei sistemi Unix/Linux. Su Windows la maggior parte dei compilatori non lo supporta (mi sembra che il compilatore Cygwin lo supporta). Da una rapida ricerca negli header del Dev-C++, ho notato che non è dichiarata da nessuna parte, quindi credo proprio che non sia disponibile con il Dev-C++.
@$te:
Il post #29 di andbin spiega bene la situazione: per wget quindi ci sei.
Per qanto riguarda la fork(): come già detto è un concetto Unix/Linux: su windows sono supportati solo i thread (quindi no duplicazione immediata - tramite system call per intenderci - dei processi).
Nessuno ti vieta di lanciare la system(), anzi, ti dirò di più. Prima ho parlato di execve:se lanci quella, il tuo processo viene sostituito dal processo specificato come parametro, quindi alla fine del comando passato alla execve, il tutto termina (non c'è ritorno...). Quindi sei costretto a lanciare un nuovo processo (o un nuovo thread parlando di Windows) il quale lanci a sua volta la execve.
Per semplificare la vita a tutti (:)), si è pensato alla system call system(), che fa tutto il lavoro per te: crea un nuovo processo (thread in windows) e lancia il comando, ritornando subito al tuo programma (evidentemente l'implementazione interna della funzione varia da sistema operativo a sistema operativo, ma è portabile quindi non devi preoccuparti, funziona ovunque). Quindi, il tuo programma ed il programma lanciato con la system procederanno insieme (nel linguaggio informatico "in modo concorrente").
Tutto questo è per spiegare il meccanismo: comunque usa system() come detto da andbin nel post precedente e sei a posto.
Per concludere, ricorda: Windows NON supporta la system call fork(), semplicemente perchè non supporta (per scelta progettuale) la duplicazione di un processo. Windows usa i thread (che puoi pensarlo come una "costola" del programma che gira autonomamente (in modo concorrente) all'interno del processo stesso).
incredibile windows....mi sa ke prossimamente iniziero ad usare linux sul pc vekkio:P cmq, se ad esempio faccio un programmino ke usa fork con linux, e poi lo compilo, poi se lo provo con windows dovrebbe andare cmq justo? ora provo come ha detto andbin!!
incredibile windows....mi sa ke prossimamente iniziero ad usare linux sul pc vekkio:P cmq, se ad esempio faccio un programmino ke usa fork con linux, e poi lo compilo, poi se lo provo con windows dovrebbe andare cmq justo? ora provo come ha detto andbin!!
purtroppo non funzionerebbe, come ti è stato spiegato la fork è una funzione di sistema di linux, un programma compilato su linux non funziona sotto windows per via delle differenti implementazioni dei sistemi operativi
incredibile windows....mi sa ke prossimamente iniziero ad usare linux sul pc vekkio:P cmq, se ad esempio faccio un programmino ke usa fork con linux, e poi lo compilo, poi se lo provo con windows dovrebbe andare cmq justo?
No, perchè gli eseguibili Linux non girano su Windows (se non usando un emulatore come CygWin), e quelli Windows non girano su Linux (a meno di usare un "emulatore" come Wine).
Per creare un eseguibile per Windows, devi compilare il sorgente su Windows (con un compilatore/linker per windows), stessa cosa per linux.
I programmi cosiddetti "portabili" sono proprio quelli che compilano su diverse piattaforme indifferentemente, perchè usano chiamate standard e/o librerie che esistono su diversi SO.
Un esempio: se vuoi usare i thread sia su Win che su Linux (quindi creare un programma che usi i thread e che compili su entrambi i SO), puoi usare la libreria pthread:
http://sourceware.org/pthreads-win32/
che come vedi esiste anche per Windows (in linux è presente di default, perchè pthread usa lo standard internazionale POSIX per il multithread, cosa che come al solito con le librerie MS non accade).
Tutto questo è un esempio se sei interessato alla portabilità delle tue applicazioni.
Ovviamente se usi le librerie fornite da MS, i tuoi programmi compileranno e gireranno solo su Windows (o su linux con Wine, se va tutto bene), ma non sempre, del resto, è richiesta la portabilità :)
Cmq la system() è una chiamata che puoi usare sia con Win che con Linux, quindi vai tranquillo (e non hai neanche bisogno di "forkare" il processo manualmente - o creare un nuovo thread - fa tutto la system() in automatico, come ho spiegato in un post precedente).
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.