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 
Host: %s 
Connection: keep-alive 

",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请求的附加信息是一行一个的。每一行我们要用 表示回车换行。而请求报头的结束标记是一个空行。所以你看上面的请求报头是以 来结束的。

  接下来就来试一下我们这个程序到底能不能用。我们先在本地搭建一个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

原文地址:https://www.cnblogs.com/wunaozai/p/3900134.html