首页 > 代码库 > Socket网络编程--网络爬虫(1)
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 409612 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