我們這個系列准備講一下--網絡爬蟲。網絡爬蟲是搜索引擎系統中十分重要的組成部分,它負責從互聯網中搜集網頁,采集信息,這些網頁信息用於建立索引從而為搜索引擎提供支持,它決定着整個引擎系統的內容是否豐富,信息是否即時,因此其性能的優劣直接影響着搜索引擎的效果。網絡爬蟲的基本工作原理:
(1)從一個初始URL集合中挑選一個URL,下載該URL對應的頁面;
(2)解析該頁面,從該頁面中抽取出其包含的URL集合,接下來將抽取的URL集合再添加到初始URL集合中;
(3)重復前兩個過程,直到爬蟲達到某種停止標准為止。
當然作為才學網絡編程不久的我肯定不能講那么復雜的東西了。在這一小節我們將實現用C語言來下載一個網頁。
實現下載一個網頁
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <sys/types.h> 5 #include <sys/socket.h> 6 #include <unistd.h> 7 #include <netdb.h> 8 #include <netinet/in.h> 9 #include <arpa/inet.h> 10 11 #define BUF_SIZE 4096 12 13 int main(int argc,char *argv[]) 14 { 15 struct sockaddr_in servAddr; 16 struct hostent * host; 17 int sockfd; 18 char sendBuf[BUF_SIZE],recvBuf[BUF_SIZE]; 19 int sendSize,recvSize; 20 21 host=gethostbyname(argv[1]); 22 if(host==NULL) 23 { 24 perror("dns 解析失敗"); 25 } 26 servAddr.sin_family=AF_INET; 27 servAddr.sin_addr=*((struct in_addr *)host->h_addr); 28 servAddr.sin_port=htons(atoi(argv[2])); 29 bzero(&(servAddr.sin_zero),8); 30 31 sockfd=socket(AF_INET,SOCK_STREAM,0); 32 if(sockfd==-1) 33 { 34 perror("socket 創建失敗"); 35 } 36 37 if(connect(sockfd,(struct sockaddr *)&servAddr,sizeof(struct sockaddr_in))==-1) 38 { 39 perror("connect 失敗"); 40 } 41 42 //構建一個http請求 43 sprintf(sendBuf,"GET / HTTP/1.1 \r\nHost: %s \r\nConnection: keep-alive \r\n\r\n",argv[1]); 44 if((sendSize=send(sockfd,sendBuf,BUF_SIZE,0))==-1) 45 { 46 perror("send 失敗"); 47 } 48 //獲取http應答信息 49 memset(recvBuf,0,sizeof(recvBuf)); 50 while(recvSize=recv(sockfd,recvBuf,BUF_SIZE,0)) 51 { 52 printf("%s",recvBuf); 53 memset(recvBuf,0,sizeof(recvBuf)); 54 } 55 56 return 0; 57 }
關於上面的構建HTTP請求的部分,可以參考網上資料或者我的博客上也有簡單講解一些(了解HTTP協議 http://www.cnblogs.com/wunaozai/p/3733432.html)
HTTP請求由三部分組成,分別是請求行,消息報頭,請求正文。我就簡單說一下上面用到的請求吧。首先GET / HTTP/1.1 表示使用GET請求方式獲取/(根目錄),使用的是http1.1版本(這個1.1好像用了很久,2.0已經開始推行了。)下一個是Host: 是發送請求資源的Internet主機和端口號。默認的端口號是80.好了一個看起來很復雜的http請求就這兩個是必須的,其他的可以不用寫的。你看是不是很容易啊。其他的參數等用到的時候在講好了。還有一個注意點,就是一個http請求的附加信息是一行一個的。每一行我們要用\r\n表示回車換行。而請求報頭的結束標記是一個空行。所以你看上面的請求報頭是以\r\n\r\n來結束的。
接下來就來試一下我們這個程序到底能不能用。我們先在本地搭建一個http服務器。放進去一個Hello World來看一下。
上面那一大堆是響應(Respond)報頭。第一行是,使用http1.1版本協議,此次的您的連接(客戶端)是200 OK 正常的。下一行是時間,服務器用的是apache。第8行Content-Length: 86表示下面的html總共有86個字節(不信,你數數看?)。下面再給一張博客園的主頁的返回信息。
上面的程序我運行是有時會出現一個問題就是獲取的網頁不完整。不知道為什么,然后我把BUF_SIZE改小一點為512就不會,也不知道為什么。然后還有一個問題就是我拉取www.baidu.com 就不知道為什么是活拉不了,不知道是不是因為我的請求報頭太少的原因?
參考資料:
http://www.cnblogs.com/coser/archive/2012/06/29/2570535.html
http://blog.csdn.net/gueter/article/details/1524447
本文地址: