zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    SSM框架搭建
    UML——类图
    javascript中的闭包(Closure)的学习
    JS和jQuery中ul li遍历获取对应的下角标
    jquery中防止冒泡事件
    chouTi
    DjangoForm 之创建FORM模板进行验证
    django学习日记-cookie
    同步锁
    进程线程
  • 原文地址:https://www.cnblogs.com/wunaozai/p/3900134.html
Copyright © 2011-2022 走看看