网络爬虫C实现http://blog.csdn.net/xu3737284/article/details/9614933

来源:互联网 发布:ug编程侧铣头走圆弧 编辑:程序博客网 时间:2024/06/05 21:05
[cpp] view plaincopy
  1. #include <sys/types.h>  
  2. #include <sys/stat.h>  
  3. #include <fcntl.h>  
  4. #include <winsock2.h>  
  5. #include <unistd.h>  
  6. #include <stdio.h>  
  7. #include <string.h>  
  8. #include <stdlib.h>  
  9. #include <errno.h>  
  10. #include <locale.h>  
  11.   
  12. #define bzero(p, s) memset(p, 0, s)  
  13. #define USERAGENT "Wget/1.10.2"  
  14. #define ACCEPT "*/*"  
  15. #define ACCEPTLANGUAGE "zh-cn,zh;q=0.5"  
  16. #define ACCEPTENCODING "gzip,deflate"  
  17. #define ACCEPTCHARSET "gb2312,utf-8;q=0.7,*;q=0.7"  
  18. #define KEEPALIVE "300"  
  19. #define CONNECTION "keep-alive"  
  20. #define CONTENTTYPE "application/x-www-form-urlencoded"  
  21.   
  22. #define MAXFILENAME 14  
  23. #define DEBUG 1  
  24.   
  25. typedef struct webnode  
  26. {  
  27.     char * host;                 /* 网页所在的主机 */  
  28.     int    port;                 /* 网络服务器所使用的端口 */  
  29.     char *  dir;                 /* 网页所在的目录 */  
  30.     char * page;                 /* 网页文件名 */  
  31.     char * file;                 /* 本地保存的文件名 */  
  32.     char IsHandled;              /* 是否处理过 */  
  33.     struct webnode * brother;    /* 兄弟节点链表指针 */  
  34.     struct webnode * child;      /* 子节点链表指针 */  
  35. } WEBNODE;  
  36.   
  37. struct sockaddr_in server_addr;  
  38. int sockfd = 0, dsend = 0, totalsend = 0, nbytes = 0, reqn = 0, i = 0, j = 0, ret = 0;  
  39. struct hostent *host;  
  40. char request[409600] = "", buffer[1024] = "", httpheader[1024] = "";  
  41. int FileNumber = 0;  
  42. char e[2] = "@/";  
  43. WEBNODE * NodeHeader, * NodeTail, * NodeCurr;  
  44. char * mapped_mem;  
  45.   
  46. int GetHost(char * , char ** , char ** , int * , char ** ); /**/  
  47. void AnalyzePage(WEBNODE *); /**/  
  48. void AddInitNode(char *, char *, intchar * ); /**/  
  49. void HandleInitNode(WEBNODE *); /**/  
  50. void DisplayNode(WEBNODE *); /**/  
  51. void HandOneNode(WEBNODE *); /**/  
  52. void DoneWithList(int); /**/  
  53. void DoOnce(); /**/  
  54. void ConnectWeb(void); /**/  
  55. void SendRequest(void); /**/  
  56. void ReceiveResponse(void); /**/  
  57. void GetEmail(char * ); /**/  
  58. void GetLink(char * ); /**/  
  59. void GetBeforePos(char * , char ** ); /**/  
  60. void GetAfterPos(char * , char ** ); /**/  
  61. void AddChildNode(WEBNODE * , char * ); /**/  
  62. void GetAfterPosWithSlash(char * , char ** ); /**/  
  63. void GetMemory(char ** , int ); /**/  
  64. int IsExistWeb(WEBNODE * , char * , char * , int , char * ); /**/  
  65. void Rstrchr(char * , int , char ** ); /**/  
  66. int GetLocalAgent(char * UserAgent, char * Accept, char * AcceptLanguage, char * AcceptEncoding, char * AcceptCharset, char * KeepAlive, char * Connection, char * ContentType); /**/  
  67.   
  68. /************************************************************** 
  69. 功能:设置 HTTP 协议头内容的一些固定值 
  70. ***************************************************************/  
  71. int GetLocalAgent(char * UserAgent, char * Accept, char * AcceptLanguage, char * AcceptEncoding, char * AcceptCharset, char * KeepAlive, char * Connection, char * ContentType)  
  72. {  
  73.     memcpy(UserAgent, USERAGENT, strlen(USERAGENT));  
  74.     memcpy(Accept, ACCEPT, strlen(ACCEPT));  
  75.     memcpy(AcceptLanguage, ACCEPTLANGUAGE, strlen(ACCEPTLANGUAGE));  
  76.     memcpy(AcceptEncoding, ACCEPTENCODING, strlen(ACCEPTENCODING));  
  77.     memcpy(AcceptCharset, ACCEPTCHARSET, strlen(ACCEPTCHARSET));  
  78.     memcpy(KeepAlive, KEEPALIVE, strlen(KEEPALIVE));  
  79.     memcpy(Connection, CONNECTION, strlen(CONNECTION));  
  80.     memcpy(ContentType, CONTENTTYPE, strlen(CONTENTTYPE));  
  81.     return 0;  
  82. }  
  83.   
  84. /************************************************************** 
  85. 功能:在字符串 s 里搜索 x 字符,并设置指针 d 指向该位置 
  86. ***************************************************************/  
  87. void Rstrchr(char * s, int x, char ** d)  
  88. {  
  89.     int len = strlen(s) - 1;  
  90.     while(len >= 0)  
  91.     {  
  92.         if(x == s[len]) {(*d) = s + len; return;}  
  93.         len--;  
  94.     }  
  95.     (*d) = 0;  
  96. }  
  97.   
  98. /************************************************************** 
  99. 功能:连接一个网站服务器 
  100. ***************************************************************/  
  101. void ConnectWeb(void)  
  102. {  
  103.     /* connect to web server */  
  104.     /* create a socket descriptor */  
  105.     if((sockfd=socket(PF_INET,SOCK_STREAM,0))==-1)  
  106.     {  
  107.         fprintf(stderr,"\tSocket Error:%s\a\n",strerror(errno));  
  108.         exit(1);  
  109.     }  
  110.   
  111.     /* bind address */  
  112.     bzero(&server_addr, sizeof(server_addr));  
  113.     server_addr.sin_family = AF_INET;  
  114.     server_addr.sin_port = htons(NodeCurr->port);  
  115.     server_addr.sin_addr = *((struct in_addr *)host->h_addr);  
  116.   
  117.     /* connect to the server */  
  118.     if(connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1)  
  119.     {  
  120.         fprintf(stderr, "\tConnect Error:%s\a\n", strerror(errno));  
  121.         exit(1);  
  122.     }  
  123. }  
  124.   
  125. /************************************************************** 
  126. 功能:向网站发送 HTTP 请求 
  127. ***************************************************************/  
  128. void SendRequest(void)  
  129. {  
  130.     /* send my http-request to web server */  
  131.     dsend = 0;totalsend = 0;  
  132.     nbytes=strlen(request);  
  133.     while(totalsend < nbytes)  
  134.     {  
  135.         dsend = write(sockfd, request + totalsend, nbytes - totalsend);  
  136.         if(dsend==-1)  {fprintf(stderr, "\tsend error!%s\n", strerror(errno));exit(0);}  
  137.         totalsend+=dsend;  
  138.         fprintf(stdout, "\n\tRequest.%d %d bytes send OK!\n", reqn, totalsend);  
  139.     }  
  140. }  
  141.   
  142. /************************************************************** 
  143. 功能:接收网站的 HTTP 返回 
  144. ***************************************************************/  
  145. void ReceiveResponse(void)  
  146. {  
  147.     /* get response from web server */  
  148.     fd_set writefds;  
  149.     struct timeval tival;  
  150.     int retry = 0;  
  151.     FILE * localfp = NULL;  
  152.   
  153.     i=0; j = 0;  
  154.     __ReCeive:  
  155.     FD_ZERO(&writefds);  
  156.     tival.tv_sec = 10;  
  157.     tival.tv_usec = 0;  
  158.     if(sockfd > 0) FD_SET(sockfd, &writefds);  
  159.     else {fprintf(stderr, "\n\tError, socket is negative!\n"); exit(0);}  
  160.   
  161.     ret = select(sockfd + 1, &writefds, NULL, NULL, &tival);  
  162.     if(ret ==0 )  
  163.     {  
  164.         if(retry++ < 10) goto __ReCeive;  
  165.     }  
  166.     if(ret <= 0) {fprintf(stderr, "\n\tError while receiving!\n"); exit(0);}  
  167.   
  168.     if(FD_ISSET(sockfd, &writefds))  
  169.     {  
  170.         memset(buffer, 0, 1024);  
  171.         memset(httpheader, 0, 1024);  
  172.         if((localfp = fopen(NodeCurr->file, "w")) == NULL) {if(DEBUG) fprintf(stderr, "create file '%s' error\n", NodeCurr->file); return;}  
  173.         /* receive data from web server */  
  174.         while((nbytes=read(sockfd,buffer,1))==1)  
  175.         {  
  176.             if(i < 4)  
  177.             {  
  178.                 /* 获取 HTTP 消息头 */  
  179.                     if(buffer[0] == '\r' || buffer[0] == '\n')  i++;  
  180.                     else i = 0;  
  181.                     memcpy(httpheader + j, buffer, 1); j++;  
  182.             }  
  183.             else  
  184.             {  
  185.                 /* 获取 HTTP 消息体 */  
  186.                     fprintf(localfp, "%c", buffer[0]); /* print content on the screen */  
  187.                     i++;  
  188.             }//else  
  189.         }//while  
  190.         fclose(localfp);  
  191.     }//if(FD_ISSET(sockfd, &writefds))  
  192. }  
  193.   
  194. /************************************************************** 
  195. 功能:执行一次 HTTP 请求 
  196. ***************************************************************/  
  197. void DoOnce()  
  198. {  
  199.     /* send and receive */  
  200.     ConnectWeb(); /* connect to the web server */  
  201.   
  202.     /* send a request */  
  203.     SendRequest();  
  204.   
  205.     /* receive a response message from web server */  
  206.     ReceiveResponse();  
  207.   
  208.     close(sockfd); /* because HTTP protocol do something one connection, so I can close it after receiving */  
  209. }  
  210.   
  211. /************************************************************** 
  212. 功能:执行 HTTP 请求 
  213. ***************************************************************/  
  214. void DoneWithList(int flag)  
  215. {  
  216.     if(flag) fprintf(stdout, "\tRequest.%d is:\n%s", ++reqn, request);  
  217.   
  218.     DoOnce();  
  219.   
  220.     if(flag) fprintf(stdout, "\n\tThe following is the response header:\n%s", httpheader);  
  221. }  
  222.   
  223. /************************************************************** 
  224. 功能:从字符串 src 中分析出网站地址和端口,并得到文件和目录 
  225. ***************************************************************/  
  226. int GetHost(char * src, char ** web, char ** file, int * port, char ** dir)  
  227. {  
  228.     char * pA, * pB, * pC;  
  229.     int len;  
  230.   
  231.     *port = 0;  
  232.     if(!(*src))  return -1;  
  233.     pA = src;  
  234.     if(!strncmp(pA, "http://", strlen("http://")))  pA = src+strlen("http://");  
  235.     else return 1;  
  236.     pB = strchr(pA, '/');  
  237.     if(pB)  
  238.     {  
  239.         len = strlen(pA) - strlen(pB);  
  240.         GetMemory(web, len);  
  241.         memcpy((*web), pA, len);  
  242.         if(*(pB+1))  
  243.         {  
  244.             Rstrchr(pB + 1, '/', &pC);  
  245.             if(pC) len = strlen(pB + 1) - strlen(pC);  
  246.             else len = 0;  
  247.             if(len > 0)  
  248.             {  
  249.                 GetMemory(dir, len);  
  250.                 memcpy((*dir), pB + 1, len);  
  251.   
  252.                 if(pC + 1)  
  253.                 {  
  254.                     len = strlen(pC + 1);  
  255.                     GetMemory(file, len);  
  256.                     memcpy((*file), pC + 1, len);  
  257.                 }  
  258.                 else  
  259.                 {  
  260.                     len = 1;  
  261.                     GetMemory(file, len);  
  262.                     memcpy((*file), e, len);  
  263.                 }// else  
  264.             }// if(len > 0)  
  265.             else  
  266.             {  
  267.                 len = 1;  
  268.                 GetMemory(dir, len);  
  269.                 memcpy((*dir), e + 1, len);  
  270.   
  271.                 len = strlen(pB + 1);  
  272.                 GetMemory(file, len);  
  273.                 memcpy((*file), pB + 1, len);  
  274.             }// else  
  275.         }// if(*(pB+1))  
  276.         else  
  277.         {  
  278.             len = 1;  
  279.             GetMemory(dir, len);  
  280.             memcpy((*dir), e + 1, len);  
  281.   
  282.             len = 1;  
  283.             GetMemory(file, len);  
  284.             memcpy((*file), e, len);  
  285.         }// else  
  286.     }// if(pB)  
  287.     else  
  288.     {  
  289.         len = strlen(pA);  
  290.         GetMemory(web, len);  
  291.         memcpy((*web), pA, strlen(pA));  
  292.         len = 1;  
  293.         GetMemory(dir, len);  
  294.         memcpy((*dir), e + 1, len);  
  295.         len = 1;  
  296.         GetMemory(file, len);  
  297.         memcpy((*file), e, len);  
  298.     }// else  
  299.   
  300.     pA = strchr((*web), ':');  
  301.     if(pA)  *port = atoi(pA + 1);  
  302.     else *port = 80;  
  303.   
  304.     return 0;  
  305. }  
  306.   
  307. /********************************************************************* 
  308. *filename: mailaddrsearch.c 
  309. *purpose: 用 C 语言编写一个网络蜘蛛来搜索网上出现的电子邮件地址 
  310. *tidied by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com) 
  311. Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言 
  312. *date time:2006-08-31 21:00:00 
  313. *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途 
  314. * 但请遵循GPL 
  315. *Thanks to: www.gd-linux.org 广东省 Linux 公共服务技术支持中心 
  316. *********************************************************************/  
  317.   
  318. int main(int argc, char ** argv)  
  319. {  
  320.     int WebPort;  
  321.     char * WebHost = 0, * PageAddress = 0, * WebDir = 0;  
  322.   
  323.     if(argc < 2) {if(DEBUG) fprintf(stdout, "Command error, you should input like this:\n\t%s WebPageAddress1 WebPageAddress2 WebPageAddress3 ...", argv[0]); exit(0);}  
  324.   
  325.     NodeHeader = NodeTail = NodeCurr = 0;  
  326.   
  327.     for(i = 1; i < argc; i++)  
  328.     {  
  329.         ret = GetHost(argv, &WebHost, &PageAddress, &WebPort, &WebDir); /* Get web page info */  
  330.         if(ret) {if(DEBUG) fprintf(stdout, "GetHost error from '%s'\n", argv); exit(0);}  
  331.         AddInitNode(WebHost, PageAddress, WebPort, WebDir); /* add this page to chain */  
  332.     }  
  333.     free(WebHost); free(PageAddress);free(WebDir);  
  334.     if(DEBUG)  
  335.     {  
  336.         fprintf(stdout, "\nDisplay.%5d:", FileNumber);  
  337.         DisplayNode(NodeHeader); /* display every node */  
  338.     }  
  339.     HandleInitNode(NodeHeader); /* handle every page */  
  340.     return 0;  
  341. }  
  342.   
  343. /************************************************************** 
  344. 功能:分析网页 
  345. ***************************************************************/  
  346. void AnalyzePage(WEBNODE * node)  
  347. {  
  348.     int fd;  
  349.     int flength = 0;  
  350.     fd = open(node->file, O_RDONLY);  
  351.     if(fd == -1)        goto __AnalyzeDone;  
  352.     flength = lseek(fd, 1, SEEK_END);  
  353.     write(fd, "\0", 1);  
  354.     lseek(fd, 0, SEEK_SET);  
  355.     mapped_mem = mmap(0, flength, PROT_READ, MAP_PRIVATE, fd, 0);  
  356.     GetEmail(mapped_mem);  
  357.     GetLink(mapped_mem);  
  358.     close(fd);  
  359.     munmap(mapped_mem, flength);  
  360. __AnalyzeDone:  
  361.     close(fd);  
  362.     node->IsHandled = 1;  
  363.     remove(node->file);  
  364. }  
  365.   
  366. /************************************************************** 
  367. 功能:为根节点设置兄弟节点 
  368. ***************************************************************/  
  369. void AddInitNode(char * Host, char * Page, int Port, char * Dir)  
  370. {  
  371.     WEBNODE * NewNode;  
  372.     char filename[MAXFILENAME + 1] = "";  
  373.   
  374.     if(NodeHeader == NULL) NewNode = NodeHeader = (WEBNODE *)malloc(sizeof(WEBNODE));  
  375.     else NodeTail->brother = NewNode = (WEBNODE *)malloc(sizeof(WEBNODE));  
  376.     memset(NewNode, 0, sizeof(WEBNODE));  
  377.     NewNode->host = (char *)malloc(strlen(Host) + 1);  
  378.     memset(NewNode->host, 0, strlen(Host) + 1);  
  379.     NewNode->page = (char *)malloc(strlen(Page) + 1);  
  380.     memset(NewNode->page, 0, strlen(Page) + 1);  
  381.     NewNode->dir = (char *)malloc(strlen(Dir) + 1);  
  382.     memset(NewNode->dir, 0, strlen(Dir) + 1);  
  383.     NewNode->file = (char *)malloc(MAXFILENAME + 1);  
  384.     memset(NewNode->file, 0, MAXFILENAME + 1);  
  385.     strcpy(NewNode->host, Host);  
  386.     strcpy(NewNode->page, Page);  
  387.     strcpy(NewNode->dir, Dir);  
  388.     sprintf(filename, "file%05d.html", FileNumber++);  
  389.     strcpy(NewNode->file, filename);  
  390.     NewNode->port = Port;  
  391.     NewNode->IsHandled = 0;  
  392.     NewNode->brother = 0;  
  393.     NewNode->child = 0;  
  394.     NodeTail = NewNode;  
  395. }  
  396.   
  397. /************************************************************** 
  398. 功能:处理根节点信息 
  399. ***************************************************************/  
  400. void HandleInitNode(WEBNODE * node)  
  401. {  
  402.     WEBNODE * CurrentNode = 0;  
  403.     CurrentNode = node;  
  404.     if(CurrentNode)  
  405.     {  
  406.         while(CurrentNode)  
  407.         {  
  408.             if(CurrentNode->IsHandled == 0)  
  409.             {  
  410.                 HandOneNode(CurrentNode);  
  411.                 if(DEBUG)  
  412.                 {  
  413.                     fprintf(stdout, "\nDisplay.%5d:", FileNumber);  
  414.                     DisplayNode(NodeHeader); /* display every node */  
  415.                 }  
  416.             }  
  417.             CurrentNode = CurrentNode->brother;  
  418.         }// while  
  419.         CurrentNode = node;  
  420.         while(CurrentNode)  
  421.         {  
  422.             if(CurrentNode->child && CurrentNode->child->IsHandled == 0)  
  423.             {  
  424.                 HandleInitNode(CurrentNode->child);  
  425.             }  
  426.             CurrentNode = CurrentNode->brother;  
  427.         }// while  
  428.     }  
  429. }  
  430.   
  431. /************************************************************** 
  432. 功能:显示年有节点信息 
  433. ***************************************************************/  
  434. void DisplayNode(WEBNODE * NodeHeader)  
  435. {  
  436.     WEBNODE * TempNode;  
  437.     TempNode = NodeHeader;  
  438.     fprintf(stdout, "\n");  
  439.     while(TempNode)  
  440.     {  
  441.         if(!strcmp(TempNode->dir, "/"))  
  442.             fprintf(stdout, "\t%s:%d%s%s => %s %d\n", TempNode->host, TempNode->port, TempNode->dir, strcmp(TempNode->page, "@")?TempNode->page:"", TempNode->file, TempNode->IsHandled);  
  443.         else  
  444.             fprintf(stdout, "\t%s:%d/%s/%s => %s %d\n", TempNode->host, TempNode->port, TempNode->dir, strcmp(TempNode->page, "@")?TempNode->page:"", TempNode->file, TempNode->IsHandled);  
  445.         TempNode = TempNode->brother;  
  446.     }// while  
  447.   
  448.     TempNode = NodeHeader;  
  449.     while(TempNode)  
  450.     {  
  451.         if(TempNode->child)  
  452.             DisplayNode(TempNode->child);  
  453.         TempNode = TempNode->brother;  
  454.     }// while  
  455. }  
  456.   
  457. /************************************************************** 
  458. 功能:处理单个节点信息 
  459. ***************************************************************/  
  460. void HandOneNode(WEBNODE * node)  
  461. {  
  462.     char UserAgent[1024] = "",  
  463.         Accept[1024] = "",  
  464.         AcceptLanguage[1024] = "",  
  465.         AcceptEncoding[1024] = "",  
  466.         AcceptCharset[1024] = "",  
  467.         KeepAlive[1024] = "",  
  468.         Connection[1024] = "",  
  469.         ContentType[1024] = "";  
  470.   
  471.     NodeCurr = node;  
  472.     if((host=gethostbyname(NodeCurr->host))==NULL) /* get ip address by domain */  
  473.     {  
  474.         if(DEBUG)  fprintf(stderr,"\tGethostname '%s' error, %s\n", NodeCurr->host, strerror(errno));  
  475.         exit(1);  
  476.     }  
  477.     GetLocalAgent(UserAgent, Accept, AcceptLanguage, AcceptEncoding, AcceptCharset, KeepAlive, Connection, ContentType); /* Get client browser information */  
  478.   
  479.     if(strcmp(NodeCurr->dir, "/"))  
  480.         sprintf(request, "GET /%s/%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\nAccept: %s\r\nConnection: %s\r\n\r\n", NodeCurr->dir, strcmp(NodeCurr->page, "@")?NodeCurr->page:"", NodeCurr->host, UserAgent, Accept, Connection);  
  481.     else  
  482.         sprintf(request, "GET %s%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\nAccept: %s\r\nConnection: %s\r\n\r\n", NodeCurr->dir, strcmp(NodeCurr->page, "@")?NodeCurr->page:"", NodeCurr->host, UserAgent, Accept, Connection);  
  483.   
  484.     DoneWithList(1);  
  485.     AnalyzePage(NodeCurr);  
  486. }  
  487.   
  488. /************************************************************** 
  489. 功能:从字符串 src 中分析出邮件地址保存到文件 
  490. ***************************************************************/  
  491. void GetEmail(char * src)  
  492. {  
  493.     char * pa, * pb, * pc, *pd;  
  494.     char myemail[1024] = "";  
  495.     FILE * mailfp = NULL;  
  496.     if((mailfp = fopen("email.txt""a+")) == NULL)  
  497.     return;  
  498.     pa = src;  
  499.     while((pb = strchr(pa, '@')))  
  500.     {  
  501.         GetBeforePos(pb, &pc);  
  502.         GetAfterPos(pb, &pd);  
  503.         if(pc && pd && (strlen(pc) > (strlen(pd) + 3)))  
  504.         {  
  505.             memset(myemail, 0, 1024);  
  506.             memcpy(myemail, pc, strlen(pc) - strlen(pd));  
  507.             if(strcmp(NodeCurr->dir, "/")) fprintf(mailfp, "%s\thttp://%s/%s/%s\n", myemail, NodeCurr->host, NodeCurr->dir, strcmp(NodeCurr->page, "@")?NodeCurr->page:"");  
  508.             else  fprintf(mailfp, "%s\thttp://%s%s%s\n", myemail, NodeCurr->host, NodeCurr->dir, strcmp(NodeCurr->page, "@")?NodeCurr->page:"");  
  509.             if(*(pd + 1))  
  510.                 pa = pd + 1;  
  511.             else break;  
  512.         }  
  513.         else if(*(pb + 1))  
  514.             pa = pb + 1;  
  515.         else  
  516.             break;  
  517.     }// while  
  518.     fclose(mailfp);  
  519. }  
  520.   
  521. /************************************************************** 
  522. 功能:从 src 中找出前面的字母、数字等内含,即 email 地址中 @ 的前面部分 
  523. ***************************************************************/  
  524. void GetBeforePos(char * src, char ** d)  
  525. {  
  526.     char * x;  
  527.     if(src - 1)  
  528.         x = src - 1;  
  529.     else {*d = 0; return ;}  
  530.     while(x)  
  531.     {  
  532.         if(*x >= 'a' && *x <= 'z') {x--; continue;}  
  533.         else if(*x >= 'A' && *x <= 'Z') {x--; continue;}  
  534.         else if(*x >= '0' && *x <= '9') {x--; continue;}  
  535.         else if(*x == '.' || *x == '-' || *x == '_') {x--; continue;}  
  536.         else {break;}  
  537.     }  
  538.     x++;  
  539.     if(x) *d = x;  
  540.     else *d = 0;  
  541. }  
  542.   
  543. /************************************************************** 
  544. 功能:从 src 中找出后面的字母、数字等内含,即 email 地址中 @ 的后面部分 
  545. ***************************************************************/  
  546. void GetAfterPos(char * src, char ** d)  
  547. {  
  548.     char * x;  
  549.     if(src + 1)  
  550.         x = src + 1;  
  551.     else {*d = 0; return ;}  
  552.   
  553.     while(x)  
  554.     {  
  555.         if(*x >= 'a' && *x <= 'z') {x++; continue;}  
  556.         else if(*x >= 'A' && *x <= 'Z') {x++; continue;}  
  557.         else if(*x >= '0' && *x <= '9') {x++; continue;}  
  558.         else if(*x == '.' || *x == '-' || *x == '_') {x++; continue;}  
  559.         else {break;}  
  560.     }  
  561.   
  562.     if(x) *d = x;  
  563.     else *d = 0;  
  564. }  
  565.   
  566. /************************************************************** 
  567. 功能:从 src 中找出前面的字母、数字等内含,即一个网页地址中主机名后面的部分 
  568. ***************************************************************/  
  569. void GetAfterPosWithSlash(char * src, char ** d)  
  570. {  
  571.     char * x;  
  572.     if(src)  
  573.     x = src;  
  574.     else {*d = 0; return ;}  
  575.   
  576.     while(x)  
  577.     {  
  578.         if(*x >= 'a' && *x <= 'z') {x++; continue;}  
  579.         else if(*x >= 'A' && *x <= 'Z') {x++; continue;}  
  580.         else if(*x >= '0' && *x <= '9') {x++; continue;}  
  581.         else if(*x == '.' || *x == '-' || *x == '_' || *x == '=') {x++; continue;}  
  582.         else if(*x == ':' || *x == '/' || *x == '?' || *x == '&') {x++; continue;}  
  583.         else {break;}  
  584.     }  
  585.     if(x) *d = x;  
  586.     else *d = 0;  
  587. }  
  588.   
  589. /************************************************************** 
  590. 功能:为 myanchor 分配 len 大小的内存 
  591. ***************************************************************/  
  592. void GetMemory(char ** myanchor, int len)  
  593. {  
  594.     if(!(*myanchor))  
  595.         (*myanchor) = (char *)malloc(len + 1);  
  596.     else  
  597.         (*myanchor) = (char *)realloc((void *)(*myanchor), len + 1);  
  598.     memset((*myanchor), 0, len + 1);  
  599. }  
  600.   
  601. /************************************************************** 
  602. 功能:从 src 中分析出网页链接,并加入到当前节点的子节点上 
  603. ***************************************************************/  
  604. void GetLink(char * src)  
  605. {  
  606.     char * pa, * pb, * pc;  
  607.     char * myanchor = 0;  
  608.     int len = 0;  
  609.   
  610.     pa = src;  
  611.     do  
  612.     {  
  613.         if((pb = strstr(pa, "href='")))  
  614.         {  
  615.             pc = strchr(pb + 6, '\'');  
  616.             len = strlen(pb + 6) - strlen(pc);  
  617.             GetMemory(&myanchor, len);  
  618.             memcpy(myanchor, pb + 6, len);  
  619.         }  
  620.         else if((pb = strstr(pa, "href=\"")))  
  621.         {  
  622.             pc = strchr(pb + 6, '"');  
  623.             len = strlen(pb + 6) - strlen(pc);  
  624.             GetMemory(&myanchor, len);  
  625.             memcpy(myanchor, pb + 6, len);  
  626.         }  
  627.         else if((pb = strstr(pa, "href=")))  
  628.         {  
  629.             GetAfterPosWithSlash(pb + 5, &pc);  
  630.             len = strlen(pb + 5) - strlen(pc);  
  631.             GetMemory(&myanchor, len);  
  632.             memcpy(myanchor, pb + 5, len);  
  633.         }  
  634.         else {goto __returnLink ;}  
  635.   
  636.         if(strlen(myanchor) > 0)  
  637.             AddChildNode(NodeCurr, myanchor);  
  638.         if(pc + 1)  
  639.             pa = pc + 1;  
  640.     }while(pa);  
  641. __returnLink:  
  642.     return;  
  643. }  
  644.   
  645. /************************************************************** 
  646. 功能:为当前节点增加子节点 
  647. ***************************************************************/  
  648. void AddChildNode(WEBNODE * node, char * src)  
  649. {  
  650.     int WebPort, len;  
  651.     char * WebHost = 0, * PageAddress = 0, * WebDir = 0, * pC = 0;  
  652.     WEBNODE * NewNode;  
  653.     char filename[MAXFILENAME + 1] = "";  
  654.     char IsFromRoot = 0;  
  655.   
  656.     if(!src)        return;  
  657.     if(!strncasecmp(src, "mailto:", strlen("mailto:")))        return ;  
  658.     if(strstr(src, ".css"))        return;  
  659.     if(strstr(src, ".xml"))        return;  
  660.     if(strstr(src, ".ico"))        return;  
  661.     if(strstr(src, ".jpg"))        return;  
  662.     if(strstr(src, ".gif"))        return;  
  663.     if(strstr(src, "javascript:"))        return;  
  664.     if(strstr(src, "+"))        return;  
  665.   
  666.     ret = GetHost(src, &WebHost, &PageAddress, &WebPort, &WebDir);  
  667.     if(ret)  
  668.     {  
  669.         len = strlen(node->host);  
  670.         GetMemory(&WebHost, len);  
  671.         strcpy(WebHost, node->host);  
  672.   
  673.         WebPort = node->port;  
  674.   
  675.         IsFromRoot = !strncmp(src, "/", 1);  
  676.         if(IsFromRoot && (src + 1))  
  677.             Rstrchr(src + 1, '/', &pC);  
  678.         else if(!IsFromRoot)  
  679.             Rstrchr(src, '/', &pC);  
  680.         else  
  681.             pC = 0;  
  682.   
  683.         if(pC)  
  684.         {  
  685.             if(IsFromRoot)  
  686.                 len = strlen(src + 1) - strlen(pC);  
  687.             else  
  688.                 len = strlen(src) - strlen(pC) + strlen(node->dir) + 1;  
  689.             GetMemory(&WebDir, len);  
  690.   
  691.             if(IsFromRoot)  
  692.                 memcpy(WebDir, src + 1, len);  
  693.             else  
  694.             {  
  695.                 memcpy(WebDir, node->dir, strlen(node->dir));  
  696.                 strcat(WebDir, "/");  
  697.                 memcpy(WebDir + strlen(node->dir) + 1, src, strlen(src) - strlen(pC));  
  698.             }  
  699.   
  700.             if(pC + 1)  
  701.             {  
  702.                 len = strlen(pC + 1);  
  703.                 GetMemory(&PageAddress, len);  
  704.                 strcpy(PageAddress, pC + 1);  
  705.             }  
  706.             else  
  707.             {  
  708.                 len = 1;  
  709.                 GetMemory(&PageAddress, len);  
  710.                 memcpy(PageAddress, e, len);  
  711.             }  
  712.         }  
  713.         else  
  714.         {  
  715.             if(IsFromRoot)  
  716.             {  
  717.                 len = 1;  
  718.                 GetMemory(&WebDir, len);  
  719.                 memcpy(WebDir, e + 1, len);  
  720.   
  721.                 len = strlen(src + 1);  
  722.                 GetMemory(&PageAddress, len);  
  723.                 memcpy(PageAddress, src + 1, len);  
  724.             }  
  725.             else  
  726.             {  
  727.                 len = strlen(node->dir);  
  728.                 GetMemory(&WebDir, len);  
  729.                 memcpy(WebDir, node->dir, len);  
  730.   
  731.                 len = strlen(src);  
  732.                 GetMemory(&PageAddress, len);  
  733.                 memcpy(PageAddress, src, len);  
  734.             }  
  735.         }  
  736.     }  
  737.     ret = IsExistWeb(NodeHeader, WebHost, PageAddress, WebPort, WebDir);  
  738.     if(ret) goto __ReturnAdd;  
  739.   
  740.     if(node->child == NULL)  
  741.         NewNode = node->child = (WEBNODE *)malloc(sizeof(WEBNODE));  
  742.     else  
  743.         NodeTail->brother = NewNode = (WEBNODE *)malloc(sizeof(WEBNODE));  
  744.   
  745.     memset(NewNode, 0, sizeof(WEBNODE));  
  746.     NewNode->host = (char *)malloc(strlen(WebHost) + 1);  
  747.     memset(NewNode->host, 0, strlen(WebHost) + 1);  
  748.     NewNode->page = (char *)malloc(strlen(PageAddress) + 1);  
  749.     memset(NewNode->page, 0, strlen(PageAddress) + 1);  
  750.     NewNode->dir = (char *)malloc(strlen(WebDir) + 1);  
  751.     memset(NewNode->dir, 0, strlen(WebDir) + 1);  
  752.     NewNode->file = (char *)malloc(MAXFILENAME + 1);  
  753.     memset(NewNode->file, 0, MAXFILENAME + 1);  
  754.     strcpy(NewNode->host, WebHost);  
  755.     strcpy(NewNode->page, PageAddress);  
  756.     strcpy(NewNode->dir, WebDir);  
  757.     sprintf(filename, "file%05d.html", FileNumber++);  
  758.     strcpy(NewNode->file, filename);  
  759.     NewNode->port = WebPort;  
  760.     NewNode->IsHandled = 0;  
  761.     NewNode->brother = 0;  
  762.     NewNode->child = 0;  
  763.     NodeTail = NewNode;  
  764.   
  765. __ReturnAdd:  
  766.     free(WebHost);  
  767.     free(PageAddress);  
  768.     free(WebDir);  
  769. }  
  770.   
  771. /************************************************************** 
  772. 功能:检查是否已经处理过的网页 
  773. ***************************************************************/  
  774. int IsExistWeb(WEBNODE * node, char * host, char * page, int port, char * dir)  
  775. {  
  776.     WEBNODE * t;  
  777.     t = node;  
  778.   
  779.     while(t)  
  780.     {  
  781.         if(!strcmp(t->host, host) && !strcmp(t->page, page) && t->port == port && !strcmp(t->dir, dir)) return 1;  
  782.         t = t->brother;  
  783.     }  
  784.     t = node;  
  785.   
  786.     while(t)  
  787.     {  
  788.         if(t->child)  
  789.         {  
  790.             ret = IsExistWeb(t->child, host, page, port, dir);  
  791.             if(ret)  
  792.                 return 2;  
  793.         }  
  794.         t = t->brother;  
  795.     }  
  796.     return 0;  
  797. }  

0 0
原创粉丝点击