wincolID:WINCOL
38538次访问,排名2887(-1)好友0人,关注者4
WINCOL的文章
原创 36 篇
翻译 0 篇
转载 24 篇
评论 12 篇
WINCOL的公告
ASP PHP J2EE
web hosting VC
最近评论
lhulcn618:我需要破解一个vb写的软件,我需要您的帮助。怎么联系您?

我lhulcn618@gmail.com

qq:75998520
agjyfm:wow gold
laiwusheng:高手,佩服
flyingboy218:以后有时间再研究
SimonYeung:虽然我看不太懂 不过编程的风格很漂亮,看起来很舒服。
文章分类
收藏
    相册
    好友
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    转载 用 C 语言编写一个网络蜘蛛来搜索网上出现的电子邮件地址收藏

    新一篇: SIP协议在VoIP中的应用 | 旧一篇: RMI 聊天 的问题

    用 C 语言编写一个网络蜘蛛来搜索网上出现的电子邮件地址


    作者:zhoulifa
    来源:http://bbs.chinaunix.net/viewthread.php?tid=821361

    可能大家经常要去互联网上搜索特定的内容,比如收集大量邮件地址,如果用 google 之类的搜索引擎是没法实现这种特定功能的,所以用 C 语言来写一个吧。它的功能就是不断去取得网络上的页面,然后分析出网页上出现的邮件地址保存下来。象个蜘蛛一样,从网络上一个网页爬向另一个网页,不停止地搜索邮件地址。

     



    即:分析程序运行时的参数,把各网页地址作为根节点加入到链表,然后从链表头开始处理各节点

    对整个链表的处理是先处理兄弟节点,流程图如下:




    然后再处理各节点的子节点,流程图如下:



    当然,这里采用了递归调用方法,处理子节点的数据时和处理整个链表一样循环处理就是了。

    /************关于本文档********************************************
    *filename: 用 C 语言编写一个网络蜘蛛来搜索网上出现的电子邮件地址
    *purpose: 一个邮址搜索程序的雏形
    *wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
    Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
    *date time:2006-08-31 21:00:00
    *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
    * 但请遵循GPL
    *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
    *********************************************************************/

    程序在运行的过程中要建立一个树形链表结构,结构图如下:




    程序启动时分析所带参数,把各参数加入到根网页节点,如果有多个参数则这个根网页有兄弟节点。
    然后从根节点开始处理这一级上各节点,把各节点网页上出现的网页链接加到该节点的子节点上,处理完当前这一级后处理子节点这一级。



    当然这只是一个原理展示程序,并没有进行优化。

    这个程序的 main 函数流程图如下:

     源代码如下: 

     

     

    #include <sys/types.h>
    #include 
    <sys/stat.h>
    #include 
    <fcntl.h>
    #include 
    <sys/mman.h>
    #include 
    <unistd.h>
    #include 
    <stdio.h>
    #include 
    <string.h>
    #include 
    <stdlib.h>
    #include 
    <netdb.h>
    #include 
    <errno.h>
    #include 
    <locale.h>

    #define USERAGENT "Wget/1.10.2"
    #define ACCEPT "*/*"
    #define ACCEPTLANGUAGE "zh-cn,zh;q=0.5"
    #define ACCEPTENCODING "gzip,deflate"
    #define ACCEPTCHARSET "gb2312,utf-8;q=0.7,*;q=0.7"
    #define KEEPALIVE "300"
    #define CONNECTION "keep-alive"
    #define CONTENTTYPE "application/x-www-form-urlencoded"

    #define MAXFILENAME 14
    #define DEBUG 1

    typedef 
    struct webnode {
            
    char * host;                 /* 网页所在的主机 */
            
    int port;                    /* 网络服务器所使用的端口 */
            
    char * dir;                  /* 网页所在的目录 */
            
    char * page;                 /* 网页文件名 */
            
    char * file;                 /* 本地保存的文件名 */
            
    char IsHandled;              /* 是否处理过 */
            
    struct webnode * brother;    /* 兄弟节点链表指针 */
            
    struct webnode * child;      /* 子节点链表指针 */
    } WEBNODE;

    struct sockaddr_in server_addr;
    int sockfd = 0, dsend = 0, totalsend = 0, nbytes = 0, reqn = 0, i = 0, j = 0, ret = 0;
    struct hostent *host;
    char request[409600= "", buffer[1024= "", httpheader[1024= "";
    int FileNumber = 0;
    char e[2= "@/";
    WEBNODE 
    * NodeHeader, * NodeTail, * NodeCurr;
    char * mapped_mem;

    int GetHost(char * , char ** , char ** , int * , char ** ); /**/
    void AnalyzePage(WEBNODE *); /**/
    void AddInitNode(char *char *intchar * ); /**/
    void HandleInitNode(WEBNODE *); /**/
    void DisplayNode(WEBNODE *); /**/
    void HandOneNode(WEBNODE *); /**/
    void DoneWithList(int); /**/
    void DoOnce(); /**/
    void ConnectWeb(void); /**/
    void SendRequest(void); /**/
    void ReceiveResponse(void); /**/
    void GetEmail(char * ); /**/
    void GetLink(char * ); /**/
    void GetBeforePos(char * , char ** ); /**/
    void GetAfterPos(char * , char ** ); /**/
    void AddChildNode(WEBNODE * , char * ); /**/
    void GetAfterPosWithSlash(char * , char ** ); /**/
    void GetMemory(char ** , int ); /**/
    int IsExistWeb(WEBNODE * , char * , char * , int , char * ); /**/
    void Rstrchr(char * , int , char ** ); /**/
    int GetLocalAgent(char * UserAgent, char * Accept, char * AcceptLanguage, char * AcceptEncoding, char * AcceptCharset, char * KeepAlive, char * Connection, char * ContentType); /**/

     

    /**************************************************************
    功能:设置 HTTP 协议头内容的一些固定值
    **************************************************************
    */
    int GetLocalAgent(char * UserAgent, char * Accept, char * AcceptLanguage, char * AcceptEncoding, char * AcceptCharset, char * KeepAlive, char * Connection, char * ContentType)
    {
      memcpy(UserAgent, USERAGENT, strlen(USERAGENT));
      memcpy(Accept, ACCEPT, strlen(ACCEPT));
      memcpy(AcceptLanguage, ACCEPTLANGUAGE, strlen(ACCEPTLANGUAGE));
      memcpy(AcceptEncoding, ACCEPTENCODING, strlen(ACCEPTENCODING));
      memcpy(AcceptCharset, ACCEPTCHARSET, strlen(ACCEPTCHARSET));
      memcpy(KeepAlive, KEEPALIVE, strlen(KEEPALIVE));
      memcpy(Connection, CONNECTION, strlen(CONNECTION));
      memcpy(ContentType, CONTENTTYPE, strlen(CONTENTTYPE));
      
    return 0;
    }

    /**************************************************************
    功能:在字符串 s 里搜索 x 字符,并设置指针 d 指向该位置
    **************************************************************
    */
    void Rstrchr(char * s, int x, char ** d)
    {
            
    int len = strlen(s) - 1;
            
    while(len >= 0)        {
                    
    if(x == s[len]) {(*d) = s + len; return;}
                    len
    --;
            }
            (
    *d) = 0;
    }

    /**************************************************************
    功能:连接一个网站服务器
    **************************************************************
    */
    void ConnectWeb(void) { /* connect to web server */
      
    /* create a socket descriptor */
      
    if((sockfd=socket(PF_INET,SOCK_STREAM,0))==-1)
      {
        fprintf(stderr,
    " Socket Error:%sa ",strerror(errno));
        exit(
    1);
      }

      
    /* bind address */
      bzero(
    &server_addr, sizeof(server_addr));
      server_addr.sin_family 
    = AF_INET;
      server_addr.sin_port 
    = htons(NodeCurr->port);
      server_addr.sin_addr 
    = *((struct in_addr *)host->h_addr);

      
    /* connect to the server */
      
    if(connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1)
      {
        fprintf(stderr, 
    " Connect Error:%sa ", strerror(errno));
        exit(
    1);
      }
    }

    /**************************************************************
    功能:向网站发送 HTTP 请求
    **************************************************************
    */
    void SendRequest(void) { /* send my http-request to web server */
      dsend 
    = 0;totalsend = 0;
      nbytes
    =strlen(request);
      
    while(totalsend < nbytes) {
        dsend 
    = write(sockfd, request + totalsend, nbytes - totalsend);
        
    if(dsend==-1)  {fprintf(stderr, " send error!%s ", strerror(errno));exit(0);}
        totalsend
    +=dsend;
        fprintf(stdout, 
    " Request.%d %d bytes send OK! ", reqn, totalsend);
      }
    }

    /**************************************************************
    功能:接收网站的 HTTP 返回
    **************************************************************
    */
    void ReceiveResponse(void) { /* get response from web server */
      fd_set writefds;
      
    struct timeval tival;
      
    int retry = 0;
      FILE 
    * localfp = NULL;

      i
    =0; j = 0;
    __ReCeive:
      FD_ZERO(
    &writefds);
      tival.tv_sec 
    = 10;
      tival.tv_usec 
    = 0;
      
    if(sockfd > 0) FD_SET(sockfd, &writefds);
      
    else {fprintf(stderr, " Error, socket is negative! "); exit(0);}

      ret 
    = select(sockfd + 1&writefds, NULL, NULL, &tival);
      
    if(ret ==0 ) {
        
    if(retry++ < 10goto __ReCeive;
      }
      
    if(ret <= 0) {fprintf(stderr, " Error while receiving! "); exit(0);}

      
    if(FD_ISSET(sockfd, &writefds))    {
        memset(buffer, 
    01024);
        memset(httpheader, 
    01024);
        
    if((localfp = fopen(NodeCurr->file, "w")) == NULL) {if(DEBUG) fprintf(stderr, "create file '%s' error ", NodeCurr->file); return;}
        
    /* receive data from web server */
        
    while((nbytes=read(sockfd,buffer,1))==1)
        {
          
    if(i < 4)  { /* 获取 HTTP 消息头 */
            
    if(buffer[0== ' ' || buffer[0== ' ')  i++;
            
    else i = 0;
            memcpy(httpheader 
    + j, buffer, 1); j++;
          }
          
    else  { /* 获取 HTTP 消息体 */
            fprintf(localfp, 
    "%c", buffer[0]); /* print content on the screen */
            
    //fprintf(stdout, "%c", buffer[0]); /* print content on the screen */
            i++;
          }
        }
        fclose(localfp);
      }
    }

    /**************************************************************
    功能:执行一次 HTTP 请求
    **************************************************************
    */
    void DoOnce() { /* send and receive */
      ConnectWeb(); 
    /* connect to the web server */

      
    /* send a request */
      SendRequest();

      
    /* receive a response message from web server */
      ReceiveResponse();

      close(sockfd); 
    /* because HTTP protocol do something one connection, so I can close it after receiving */
    }

    /**************************************************************
    功能:执行 HTTP 请求
    **************************************************************
    */
    void DoneWithList(int flag) {
      
    if(flag) fprintf(stdout, " Request.%d is: %s"++reqn, request);

      DoOnce();

      
    if(flag) fprintf(stdout, " The following is the response header: %s", httpheader);
    }

    /**************************************************************
    功能:从字符串 src 中分析出网站地址和端口,并得到文件和目录
    **************************************************************
    */
    int GetHost(char * src, char ** web, char ** file, int * port, char ** dir)  {
      
    char * pA, * pB, * pC;
      
    int len;

      
    *port = 0;
      
    if(!(*src))  return -1;
      pA 
    = src;
      
    if(!strncmp(pA, "http://", strlen("http://")))  pA = src+strlen("http://");
      
    /* else if(!strncmp(pA, "https://", strlen("https://")))  pA = src+strlen("https://"); */
      
    else return 1;
      pB 
    = strchr(pA, '/');
      
    if(pB)  {
        len 
    = strlen(pA) - strlen(pB);
        GetMemory(web, len);
        memcpy((
    *web), pA, len);
        
    if(*(pB+1))  {
          Rstrchr(pB 
    + 1'/'&pC);
          
    if(pC) len = strlen(pB + 1- strlen(pC);
          
    else len = 0;
          
    if(len > 0) {
            GetMemory(dir, len);
            memcpy((
    *dir), pB + 1, len);

            
    if(pC + 1) {
              len 
    = strlen(pC + 1);
              GetMemory(file, len);
              memcpy((
    *file), pC + 1, len);
            }
            
    else {
              len 
    = 1;
              GetMemory(file, len);
              memcpy((
    *file), e, len);
            }
          }
          
    else {
            len 
    = 1;
            GetMemory(dir, len);
            memcpy((
    *dir), e + 1, len);

            len 
    = strlen(pB + 1);
            GetMemory(file, len);
            memcpy((
    *file), pB + 1, len);
          }
        }
        
    else {
          len 
    = 1;
          GetMemory(dir, len);
          memcpy((
    *dir), e + 1, len);

          len 
    = 1;
          GetMemory(file, len);
          memcpy((
    *file), e, len);
        }
      }
      
    else  {
        len 
    = strlen(pA);
        GetMemory(web, len);
        memcpy((
    *web), pA, strlen(pA));
        len 
    = 1;
        GetMemory(dir, len);
        memcpy((
    *dir), e + 1, len);
        len 
    = 1;
        GetMemory(file, len);
        memcpy((
    *file), e, len);
      }

      pA 
    = strchr((*web), ':');
      
    if(pA)  *port = atoi(pA + 1);
      
    else *port = 80;

      
    return 0;
    }

     

    /*********************************************************************
    *filename: mailaddrsearch.c
    *purpose: 用 C 语言编写一个网络蜘蛛来搜索网上出现的电子邮件地址
    *tidied by: zhoulifa(zhoulifa@163.com) 周立发(
    http://zhoulifa.bokee.com)
    Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
    *date time:2006-08-31 21:00:00
    *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
    * 但请遵循GPL
    *Thanks to: www.gd-linux.org 广东省 Linux 公共服务技术支持中心
    ********************************************************************
    */

    int main(int argc, char ** argv)
    {
            
    int WebPort;
            
    char * WebHost = 0* PageAddress = 0* WebDir = 0;

            
    if(argc < 2) {if(DEBUG) fprintf(stdout, "Command error, you should input like this: %s WebPageAddress1 WebPageAddress2 WebPageAddress3 ...", argv[0]); exit(0);}

            NodeHeader 
    = NodeTail = NodeCurr = 0;
            
    //setlocale(LC_ALL, "zh_CN.gb2312");
            for(i = 1; i < argc; i++)        {
                    ret 
    = GetHost(argv, &WebHost, &PageAddress, &WebPort, &WebDir); /* Get web page info */
                    
    if(ret)        {if(DEBUG) fprintf(stdout, "GetHost error from '%s' ", argv); exit(0);}
                    AddInitNode(WebHost, PageAddress, WebPort, WebDir); 
    /* add this page to chain */
            }
            free(WebHost); free(PageAddress);free(WebDir);
            
    if(DEBUG)        {
                    fprintf(stdout, 
    " Display.%5d:", FileNumber);
                    DisplayNode(NodeHeader); 
    /* display every node */
            }
            HandleInitNode(NodeHeader); 
    /* handle every page */
            
    return 0;
    }

     

    /**************************************************************
    功能:分析网页
    **************************************************************
    */
    void AnalyzePage(WEBNODE * node)
    {
            
    int fd;
            
    int flength = 0;
            fd 
    = open(node->file, O_RDONLY);
            
    if(fd == -1)        goto __AnalyzeDone;
            flength 
    = lseek(fd, 1, SEEK_END);
            write(fd, 
    "\0"1);
            lseek(fd, 
    0, SEEK_SET);
            mapped_mem 
    = mmap(0, flength, PROT_READ, MAP_PRIVATE, fd, 0);
            GetEmail(mapped_mem);
            GetLink(mapped_mem);
            close(fd);
            munmap(mapped_mem, flength);
    __AnalyzeDone:
            close(fd);
            node
    ->IsHandled = 1;
            remove(node
    ->file);
    }

    /**************************************************************
    功能:为根节点设置兄弟节点
    **************************************************************
    */
    void AddInitNode(char * Host, char * Page, int Port, char * Dir)
    {
            WEBNODE 
    * NewNode;
            
    char filename[MAXFILENAME + 1= "";

            
    if(NodeHeader == NULL) NewNode = NodeHeader = (WEBNODE *)malloc(sizeof(WEBNODE));
            
    else NodeTail->brother = NewNode = (WEBNODE *)malloc(sizeof(WEBNODE));
            memset(NewNode, 
    0sizeof(WEBNODE));
            NewNode
    ->host = (char *)malloc(strlen(Host) + 1);
            memset(NewNode
    ->host, 0, strlen(Host) + 1);
            NewNode
    ->page = (char *)malloc(strlen(Page) + 1);
            memset(NewNode
    ->page, 0, strlen(Page) + 1);
            NewNode
    ->dir = (char *)malloc(strlen(Dir) + 1);
            memset(NewNode
    ->dir, 0, strlen(Dir) + 1);
            NewNode
    ->file = (char *)malloc(MAXFILENAME + 1);
            memset(NewNode
    ->file, 0, MAXFILENAME + 1);
            strcpy(NewNode
    ->host, Host);
            strcpy(NewNode
    ->page, Page);
            strcpy(NewNode
    ->dir, Dir);
            sprintf(filename, 
    "file%05d.html", FileNumber++);
            strcpy(NewNode
    ->file, filename);
            NewNode
    ->port = Port;
            NewNode
    ->IsHandled = 0;
            NewNode
    ->brother = 0;
            NewNode
    ->child = 0;
            NodeTail 
    = NewNode;
    }

    /**************************************************************
    功能:处理根节点信息
    **************************************************************
    */
    void HandleInitNode(WEBNODE * node)
    {
            WEBNODE 
    * CurrentNode = 0;
            CurrentNode 
    = node;
            
    if(CurrentNode)        {
                    
    while(CurrentNode)        {
                            
    if(CurrentNode->IsHandled == 0)        {
                                    HandOneNode(CurrentNode);
                                    
    if(DEBUG)        {
                                            fprintf(stdout, 
    " Display.%5d:", FileNumber);
                                            DisplayNode(NodeHeader); 
    /* display every node */
                                    }
                            }
                            CurrentNode 
    = CurrentNode->brother;
                    }
                    CurrentNode 
    = node;
                    
    while(CurrentNode)        {
                            
    if(CurrentNode->child && CurrentNode->child->IsHandled == 0)        {
                                    HandleInitNode(CurrentNode
    ->child);
                            }
                            CurrentNode 
    = CurrentNode->brother;
                    }
            }
    }

    /**************************************************************
    功能:显示年有节点信息
    **************************************************************
    */
    void DisplayNode(WEBNODE * NodeHeader)
    {
            WEBNODE 
    * TempNode;
            TempNode 
    = NodeHeader;
            fprintf(stdout, 
    " ");
            
    while(TempNode) {
                    
    if(!strcmp(TempNode->dir, "/"))        fprintf(stdout, " %s:%d%s%s => %s %d ", TempNode->host, TempNode->port, TempNode->dir, strcmp(TempNode->page, "@")?TempNode->page:"", TempNode->file, TempNode->IsHandled);
                    
    else        fprintf(stdout, " %s:%d/%s/%s => %s %d ", TempNode->host, TempNode->port, TempNode->dir, strcmp(TempNode->page, "@")?TempNode->page:"", TempNode->file, TempNode->IsHandled);
                    TempNode 
    = TempNode->brother;
            }
            TempNode 
    = NodeHeader;
            
    while(TempNode) {
                    
    if(TempNode->child)        DisplayNode(TempNode->child);
                    TempNode 
    = TempNode->brother;
            }
    }

    /**************************************************************
    功能:处理单个节点信息
    **************************************************************
    */
    void HandOneNode(WEBNODE * node)
    {
            
    char UserAgent[1024= "", Accept[1024= "", AcceptLanguage[1024= "", AcceptEncoding[1024= "", AcceptCharset[1024= "", KeepAlive[1024= "", Connection[1024= "", ContentType[1024= "";

            NodeCurr 
    = node;
            
    if((host=gethostbyname(NodeCurr->host))==NULL) /* get ip address by domain */
            {
                    
    if(DEBUG)  fprintf(stderr," Gethostname '%s' error, %s ", NodeCurr->host, strerror(errno));
                    exit(
    1);
            }
            GetLocalAgent(UserAgent, Accept, AcceptLanguage, AcceptEncoding, AcceptCharset, KeepAlive, Connection, ContentType); 
    /* Get client browser information */

            
    if(strcmp(NodeCurr->dir, "/"))        sprintf(request, "GET /%s/%s HTTP/1.0 Host: %s User-Agent: %s Accept: %s Connection: %s ", NodeCurr->dir, strcmp(NodeCurr->page, "@")?NodeCurr->page:"", NodeCurr->host, UserAgent, Accept, Connection);
            
    else        sprintf(request, "GET %s%s HTTP/1.0 Host: %s User-Agent: %s Accept: %s Connection: %s ", NodeCurr->dir, strcmp(NodeCurr->page, "@")?NodeCurr->page:"", NodeCurr->host, UserAgent, Accept, Connection);
            DoneWithList(
    1);
            AnalyzePage(NodeCurr);
    }

    /**************************************************************
    功能:从字符串 src 中分析出邮件地址保存到文件
    **************************************************************
    */
    void GetEmail(char * src)
    {
            
    char * pa, * pb, * pc, *pd;
            
    char myemail[1024= "";
            FILE 
    * mailfp = NULL;
            
    if((mailfp = fopen("email.txt""a+")) == NULL)        return;
            pa 
    = src;
            
    while((pb = strchr(pa, '@')))        {
                    GetBeforePos(pb, 
    &pc);
                    GetAfterPos(pb, 
    &pd);
                    
    if(pc && pd && (strlen(pc) > (strlen(pd) + 3)))        {
                            memset(myemail, 
    01024);
                            memcpy(myemail, pc, strlen(pc) 
    - strlen(pd));
                            
    if(strcmp(NodeCurr->dir, "/")) fprintf(mailfp, "%s http://%s/%s/%s ", myemail, NodeCurr->host, NodeCurr->dir, strcmp(NodeCurr->page, "@")?NodeCurr->page:"");
                            
    else  fprintf(mailfp, "%s http://%s%s%s ", myemail, NodeCurr->host, NodeCurr->dir, strcmp(NodeCurr->page, "@")?NodeCurr->page:"");
                            
    if(*(pd + 1))        pa = pd + 1;
                            
    else break;
                    }
                    
    else if(*(pb + 1))        pa = pb + 1;
                    
    else        break;
            }
            fclose(mailfp);
    }

    /**************************************************************
    功能:从 src 中找出前面的字母、数字等内含,即 email 地址中 @ 的前面部分
    **************************************************************
    */
    void GetBeforePos(char * src, char ** d)
    {
            
    char * x;
            
    if(src - 1)        x = src - 1;
            
    else {*= 0return ;}
            
    while(x)        {
                    
    if(*>= 'a'<