Socket網絡編程--網絡爬蟲(1)


  我們這個系列准備講一下--網絡爬蟲。網絡爬蟲是搜索引擎系統中十分重要的組成部分,它負責從互聯網中搜集網頁,采集信息,這些網頁信息用於建立索引從而為搜索引擎提供支持,它決定着整個引擎系統的內容是否豐富,信息是否即時,因此其性能的優劣直接影響着搜索引擎的效果。網絡爬蟲的基本工作原理:

  (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

  本文地址:

  http://www.cnblogs.com/wunaozai/p/3900134.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM