免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: zhoulifa
打印 上一主题 下一主题

[原创] 用 C 语言编写一个网络蜘蛛来搜索网上出现的电子邮件地址 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2006-09-07 12:48 |显示全部楼层
原帖由 GNM 于 2006-9-7 12:28 发表
程序运行也有问题(as4上编译)
[root@test09.news.sina ~]# ./spdir http://bn.sina.com.cn/pv/index.html
GetHost error from '蜜窨僳窨'


打印出这行提示是这一句程序:
if(ret)        {if(DEBUG) fprintf(stdout, "GetHost error from '%s'\n", argv); exit(0);}

而程序里用的是argv,理论上应该是http://bn.sina.com.cn/pv/index.html啊
我写了测试代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>

  4. char e[2] = "@/";

  5. void GetMemory(char ** myanchor, int len)
  6. {
  7.         if(!(*myanchor))        (*myanchor) = (char *)malloc(len + 1);
  8.         else        (*myanchor) = (char *)realloc((void *)(*myanchor), len + 1);
  9.         memset((*myanchor), 0, len + 1);
  10. }

  11. void Rstrchr(char * s, int x, char ** d)
  12. {
  13.         int len = strlen(s) - 1;
  14.         while(len >= 0)        {
  15.                 if(x == s[len]) {(*d) = s + len; return;}
  16.                 len--;
  17.         }
  18.         (*d) = 0;
  19. }

  20. int GetHost(char * src, char ** web, char ** file, int * port, char ** dir)  {
  21.   char * pA, * pB, * pC;
  22.   int len;

  23.   *port = 0;
  24.   if(!(*src))  return -1;
  25.   pA = src;
  26.   if(!strncmp(pA, "http://", strlen("http://")))  pA = src+strlen("http://");
  27.   /* else if(!strncmp(pA, "https://", strlen("https://")))  pA = src+strlen("https://"); */
  28.   else return 1;
  29.   pB = strchr(pA, '/');
  30.   if(pB)  {
  31.     len = strlen(pA) - strlen(pB);
  32.     GetMemory(web, len);
  33.     memcpy((*web), pA, len);
  34.     if(*(pB+1))  {
  35.       Rstrchr(pB + 1, '/', &pC);
  36.       if(pC) len = strlen(pB + 1) - strlen(pC);
  37.       else len = 0;
  38.       if(len > 0) {
  39.         GetMemory(dir, len);
  40.         memcpy((*dir), pB + 1, len);

  41.         if(pC + 1) {
  42.           len = strlen(pC + 1);
  43.           GetMemory(file, len);
  44.           memcpy((*file), pC + 1, len);
  45.         }
  46.         else {
  47.           len = 1;
  48.           GetMemory(file, len);
  49.           memcpy((*file), e, len);
  50.         }
  51.       }
  52.       else {
  53.         len = 1;
  54.         GetMemory(dir, len);
  55.         memcpy((*dir), e + 1, len);

  56.         len = strlen(pB + 1);
  57.         GetMemory(file, len);
  58.         memcpy((*file), pB + 1, len);
  59.       }
  60.     }
  61.     else {
  62.       len = 1;
  63.       GetMemory(dir, len);
  64.       memcpy((*dir), e + 1, len);

  65.       len = 1;
  66.       GetMemory(file, len);
  67.       memcpy((*file), e, len);
  68.     }
  69.   }
  70.   else  {
  71.     len = strlen(pA);
  72.     GetMemory(web, len);
  73.     memcpy((*web), pA, strlen(pA));
  74.     len = 1;
  75.     GetMemory(dir, len);
  76.     memcpy((*dir), e + 1, len);
  77.     len = 1;
  78.     GetMemory(file, len);
  79.     memcpy((*file), e, len);
  80.   }

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

  84.   return 0;
  85. }

  86. int main(int argc, char ** argv)
  87. {
  88.         int ret = 0, WebPort = 0;
  89.         char * WebHost = 0, * PageAddress = 0, * WebDir = 0;

  90.         ret = GetHost(argv[1], &WebHost, &PageAddress, &WebPort, &WebDir); /* Get web page info */
  91.         if(ret)        {fprintf(stdout, "GetHost error from '%s'\n", argv[1]); exit(0);}
  92.         else fprintf(stdout, "'%s' => %s:%d %s %s\n", argv[1], WebHost, WebPort, WebDir, PageAddress);
  93.         return 0;
  94. }
复制代码


运行结果为:
test@locale:/source/example/c$ gcc gethost.c -Wall
test@locale:/source/example/c$ ./a.out http://bn.sina.com.cn/pv/index.html
'http://bn.sina.com.cn/pv/index.html' => bn.sina.com.cn:80 pv index.html


GNM,你在你电脑上试试这段代码看行不行

论坛徽章:
0
12 [报告]
发表于 2006-09-07 12:54 |显示全部楼层
原帖由 cmzhubill 于 2006-9-6 20:29 发表
可以在开源的爬虫,例如larbin的基础上稍作修改就能达到这个目的啊

larbin是C++写的,效率非常高。


多谢提供一份源码参考!

我下载了个larbin-2.6.3来,不过编译通不过,adns__parse_domain的申明和实现不一致
申明为internal.h:570行:
adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu,
                               vbuf *vb, parsedomain_flags flags,
                               const byte *dgram, int dglen, int *cbyte_io, int max);

实现却为parse.c:114行:
adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu,
                               vbuf *vb, adns_queryflags flags,
                               const byte *dgram, int dglen, int *cbyte_io, int max)
我学习学习这份代码再说吧,原理不会差很多吧

论坛徽章:
0
13 [报告]
发表于 2006-09-07 18:25 |显示全部楼层
GNM , 实在想不出你那是什么问题了
要不你把你那份源码发过来我这里试试看 zhoulifa@163.com

论坛徽章:
0
14 [报告]
发表于 2006-09-08 08:24 |显示全部楼层
原帖由 GNM 于 2006-9-7 21:55 发表
和你第一页的源代码一样的,楼主可以在as4或redhat8.0下试试


已经好久不用Red Hat的东西了,感觉它太难用了 :(
不过,我会在虚拟机里来试试它

论坛徽章:
0
15 [报告]
发表于 2006-09-08 18:16 |显示全部楼层
原帖由 goldeagle 于 2006-9-7 22:43 发表
辛苦了,不过,恩…… why not nutch?


不交流不知道,上面 cmzhubill 介绍了larbin,这里又来了个nutch,其它这方面成熟的软件还真不少,可惜以前不知道。
想请教一下cmzhubill 和 goldeagle ,你们是怎么知道这样的好软件的呢?
怎样才能方便快捷地发现好软件呢?

论坛徽章:
0
16 [报告]
发表于 2006-09-10 13:56 |显示全部楼层
GNM , zhumao :
我这里实在找不到一个类似你们所说的版本,太久不用Red Hat的东西了,而下载速度又不快。我刚才在一个Red Hat版本里做过实验,这是我的Red Hat版本:
[root@sunny ~]# uname -a
Linux sunny 2.6.9-5.EL #1 Wed Jan 5 19:22:18 EST 2005 i686 i686 i386 GNU/Linux
[root@sunny ~]# gcc -v
Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux
Thread model: posix
gcc version 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)


我实验结果也是没问题的,输出内容是:

  1. [root@sunny ~]# gcc -Wall -g mailsearch.c
  2. [root@sunny ~]# ./a.out "http://bn.sina.com.cn/pv/index.html"

  3. Display.    1:
  4.         bn.sina.com.cn:80/pv/index.html => file00000.html 0
  5.         Request.1 is:
  6. GET /pv/index.html HTTP/1.0
  7. Host: bn.sina.com.cn
  8. User-Agent: Wget/1.10.2
  9. Accept: */*
  10. Connection: keep-alive


  11.         Request.1 115 bytes send OK!

  12.         The following is the response header:
  13. HTTP/1.1 200 OK
  14. Date: Sun, 10 Sep 2006 05:39:53 GMT
  15. Server: Apache/1.3.27 (Unix)
  16. Last-Modified: Sun, 10 Sep 2006 05:32:00 GMT
  17. ETag: "1d7652-13296-4503a350"
  18. Accept-Ranges: bytes
  19. Content-Length: 78486
  20. Keep-Alive: timeout=15, max=10000
  21. Connection: Keep-Alive
  22. Content-Type: text/html


  23. Display.   56:
  24.         bn.sina.com.cn:80/pv/index.html => file00000.html 1

  25.         bn.sina.com.cn:80/bbs/p/2006/0906/16121295.html => file00001.html 0
  26.         bn.sina.com.cn:80/bbs/p/2006/0906/14121292.html => file00002.html 0
  27.         bn.sina.com.cn:80/bbs/p/2006/0905/15431284.html => file00003.html 0
  28.         bn.sina.com.cn:80/bbs/p/2006/0901/14251263.html => file00004.html 0
  29.         bn.sina.com.cn:80/bbs/p/2006/0901/14131261.html => file00005.html 0
  30.         bn.sina.com.cn:80/bbs/p/2006/0901/14151262.html => file00006.html 0
  31.         bn.sina.com.cn:80/bbs/p/2006/0830/15271245.html => file00007.html 0
  32.         bn.sina.com.cn:80/bbs/p/2006/0904/15471273.html => file00008.html 0
  33.         bn.sina.com.cn:80/bbs/p/2006/0904/16091275.html => file00009.html 0
  34.         bn.sina.com.cn:80/bbs/p/2006/0905/15151283.html => file00010.html 0
  35.         bn.sina.com.cn:80/dv/mmx.html => file00011.html 0
  36.         bn.sina.com.cn:80/dv/flashgame.html => file00012.html 0
  37.         bn.sina.com.cn:80/dv/flashgame.htm => file00013.html 0
  38.         bn.sina.com.cn:80/pv/# => file00014.html 0
  39.         bn.sina.com.cn:80/dv/eryueyatou.html => file00015.html 0
  40.         bn.sina.com.cn:80/bbs/2006/0427/1452523.html => file00016.html 0
  41.         bn.sina.com.cn:80/bbs/2006/0330/1831383.html => file00017.html 0
  42.         bn.sina.com.cn:80/pv/moshu.html => file00018.html 0
  43.         bn.sina.com.cn:80/dv/streetmagicians.html => file00019.html 0
  44.         bn.sina.com.cn:80/blog/index.html => file00020.html 0
  45.         bn.sina.com.cn:80/dv/huwai/index.shtml => file00021.html 0
  46.         bn.sina.com.cn:80/bbs/p/2006/0719/1651999.html => file00022.html 0
  47.         bn.sina.com.cn:80/bbs/p/2006/0717/1534979.html => file00023.html 0
  48.         bn.sina.com.cn:80/bbs/p/2006/0712/1839950.html => file00024.html 0
  49.         bn.sina.com.cn:80/bbs/p/2006/0605/1124684.html => file00025.html 0
  50.         bn.sina.com.cn:80/bbs/p/2006/0524/1623620.html => file00026.html 0
  51.         bn.sina.com.cn:80/bbs/p/2006/0607/1835714.html => file00027.html 0
  52.         bn.sina.com.cn:80/bbs/p/2006/0511/1435560.html => file00028.html 0
  53.         bn.sina.com.cn:80/bbs/p/2006/0517/1633575.html => file00029.html 0
  54.         bn.sina.com.cn:80/bbs/2006/0406/1110426.html => file00030.html 0
  55.         bn.sina.com.cn:80/dv/funny/index.shtml => file00031.html 0
  56.         bn.sina.com.cn:80/dv/love2006.html => file00032.html 0
  57.         auto.sina.com.cn:80/z/shipin/index.shtml => file00033.html 0
  58.         www.22film.com:80/ => file00034.html 0
  59.         www.streetballa.com:80/ => file00035.html 0
  60.         www.dvchina.cn:80/ => file00036.html 0
  61.         new.dvchina.cn:80/ => file00037.html 0
  62.         www.20802.com:80/ => file00038.html 0
  63.         www.cetv.edu.cn:80/program/a0908/index.php => file00039.html 0
  64.         www.pop-photo.com.cn:80/index.html => file00040.html 0
  65.         www.chndv.cn:80/ => file00041.html 0
  66.         www.pconline.com.cn:80/digital/dv/ => file00042.html 0
  67.         www.nbdv.net:80/ => file00043.html 0
  68.         www.3cworld.com.cn:80/ => file00044.html 0
  69.         www.bjlongs.com:80/ => file00045.html 0
  70.         www.tailenet.com:80/ => file00046.html 0
  71.         corp.sina.com.cn:80/chn/ => file00047.html 0
  72.         corp.sina.com.cn:80/eng/ => file00048.html 0
  73.         ads.sina.com.cn:80/ => file00049.html 0
  74.         corp.sina.com.cn:80/chn/sina_job.html => file00050.html 0
  75.         www.sina.com.cn:80/intro/lawfirm.shtml => file00051.html 0
  76.         englishcenter.sina.com:80/ => file00052.html 0
  77.         unipro.sina.com.cn:80/cgi-bin/regist0.cgi?url1=&url2=&id1=1&id2=0&entry=people&mcheck=bb25a9cc2d921f9d191ea3c76c7278b7 => file00053.html 0
  78.         tech.sina.com.cn:80/focus/sinahelp.shtml => file00054.html 0
  79.         home.sina.com.cn:80/intro/copyright.shtml => file00055.html 0
  80.         Request.2 is:
  81. GET /bbs/p/2006/0906/16121295.html HTTP/1.0
  82. Host: bn.sina.com.cn
  83. User-Agent: Wget/1.10.2
  84. Accept: */*
  85. Connection: keep-alive


  86.         Request.2 131 bytes send OK!
复制代码


我仔细比较了你们的系统和我的系统,除了gcc版本不同外,另外一个最重要的差别是内核版本我这里是2.6,而你们都是2.4的,不知道是不是这个问题。

建议你们用Debian、Ubuntu之类的试试,所有的软件包管理一个apt命令搞定,不需要自己去到处找包,不需要自己解决包之前的依赖关系。找软件用命令:

  1. apt-cache search x
复制代码

注:这里x是软件包名称或这个软件包的描述字符中的一个
安装软件用命令:

  1. apt-get install x
复制代码


比如我这里:
test@local:~$ apt-cache search crawler
htdig - WWW search system for an intranet or small internet
htdig-doc - Documentation for the htdig package
test@local:~$ sudo apt-get install htdig
Password:
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
将会安装下列额外的软件包:
  gawk libdb2 lockfile-progs
建议安装的软件包:
  catdoc pstotext gs xpdf xpdf-i
推荐安装的软件包:
  wwwoffle htdig-doc
下列【新】软件包将被安装:
  gawk htdig libdb2 lockfile-progs
共升级了 0 个软件包,新安装了 4 个软件包,要卸载 0 个软件包,有 2 个软件未被升级。
需要下载 2112kB 的软件包。
解压缩后会消耗掉 6119kB 的额外空间。
您希望继续执行吗?[Y/n]

你只需要确认一下,需要安装的4个软件包就会自动安装完成,不用你自己去找。开发人员可以专心地去做程序而省去了搜索软件包的麻烦。

Red Hat说实在地太商业化了,不是开发人员用的版本。

论坛徽章:
0
17 [报告]
发表于 2006-09-10 14:02 |显示全部楼层
原帖由 benlan 于 2006-9-8 22:41 发表
给楼主一个建议

楼主可以把mail分析加入larbin的协议处理里,然后看能否提到larbin project中

另:我的建议是楼主最好是去作wap处理,而不是mail处理,在larbin中加入wap的协议处理也许更有价值,也许还有商 ...


非常感谢你的建议,因为我这里是演示原理,所以根本没考虑其它东西。  :(
wap协议我也很有兴趣,应该不久会研究到。
但我缺少商业头脑,只能等哪天兴趣来了再抬头把所有研究的东西商业化一下。

Anyway, thanks a lot!

论坛徽章:
0
18 [报告]
发表于 2006-09-10 14:04 |显示全部楼层
原帖由 yancncen 于 2006-9-8 23:43 发表
建议楼主在检查是否已经爬取过的网站的时候可以采用hash的方法,larbin是这样做的,我觉得那样更简单高效.


谢谢,我已经下载了larbin,正在准备学习它的代码
往后如果想把这个程序做好点我肯定会参考larbin, nutch等先进代码的

论坛徽章:
0
19 [报告]
发表于 2006-09-11 17:20 |显示全部楼层
原帖由 zliming 于 2006-9-11 10:40 发表
/**************************************************************
功能:从 src 中找出前面的字母、数字等内含,即 email 地址中 @ 的前面部分
*********************************************************** ...


试一下下面的代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>

  4. void GetBeforePos(char * src, char ** d)
  5. {
  6.   char * x;
  7.   if(src - 1)  x = src - 1;
  8.   else {*d = 0; return ;}
  9.   while(x)  {
  10.     if(*x >= 'a' && *x <= 'z') {x--; continue;}
  11.     else if(*x >= 'A' && *x <= 'Z') {x--; continue;}
  12.     else if(*x >= '0' && *x <= '9') {x--; continue;}
  13.     else if(*x == '.' || *x == '-' || *x == '_') {x--; continue;}
  14.     else {break;}
  15.   }
  16.   x++;
  17.   if(x) *d = x;
  18.   else *d = 0;
  19. }

  20. int main(int argc, char ** argv)
  21. {
  22.   char * p;
  23.   char * at;
  24.   if(argc != 2)  {
  25.     printf("1 参数个数不对,请输入一个参数,若有空格请用引号,比如:%s \"mailto: zhoulifa@163.com\"", argv[1]);
  26.     exit(1);
  27.   }
  28.   at = strchr(argv[1], '@');
  29.   if(!at)  {
  30.     printf("2 参数不对,请输入包含 @ 符号的参数,比如:%s \"mailto:zhoulifa@163.com\"", argv[1]);
  31.     exit(2);
  32.   }
  33.   GetBeforePos(at, &p);
  34.   *at = 0;
  35.   printf("邮件地址前面部分为:%s\n", p);
  36.   return 0;
  37. }
复制代码


保存此程序为GetBefore.c,然后编译并运行它,如下:
test@local:/source/example/c$ gcc GetBefore.c -Wall -g
test@local:/source/example/c$ ./a.out "mail: zhoulifa@163.com"
邮件地址前面部分为:zhoulifa
test@local:/source/example/c$ ./a.out "mail:zhoulifa@163.com"
邮件地址前面部分为:zhoulifa
test@local:/source/example/c$ ./a.out "发邮件至zhoulifa@163.com"
邮件地址前面部分为:zhoulifa


明白了没?
该函数功能就是:
[size=+3]从一个标准电子邮件地址字符串,比如zhoulifa@163.com中,找出@前面部分字符

论坛徽章:
0
20 [报告]
发表于 2006-09-11 17:22 |显示全部楼层
goldeagle , yancncen :
    多谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP