`
varsoft
  • 浏览: 2510027 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

[转]用 C 语言编写一个网络蜘蛛

阅读更多

用 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>

#defineUSERAGENT"Wget/1.10.2"
#defineACCEPT"*/*"
#defineACCEPTLANGUAGE"zh-cn,zh;q=0.5"
#defineACCEPTENCODING"gzip,deflate"
#defineACCEPTCHARSET"gb2312,utf-8;q=0.7,*;q=0.7"
#defineKEEPALIVE"300"
#defineCONNECTION"keep-alive"
#defineCONTENTTYPE"application/x-www-form-urlencoded"

#defineMAXFILENAME14
#defineDEBUG1

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

structsockaddr_inserver_addr;
intsockfd=0,dsend=0,totalsend=0,nbytes=0,reqn=0,i=0,j=0,ret=0;
structhostent*host;
charrequest[409600]="",buffer[1024]="",httpheader[1024]="";
intFileNumber=0;
chare[2]="@/";
WEBNODE
*NodeHeader,*NodeTail,*NodeCurr;
char*mapped_mem;

intGetHost(char*,char**,char**,int*,char**);/**/
voidAnalyzePage(WEBNODE*);/**/
voidAddInitNode(char*,char*,int,char*);/**/
voidHandleInitNode(WEBNODE*);/**/
voidDisplayNode(WEBNODE*);/**/
voidHandOneNode(WEBNODE*);/**/
voidDoneWithList(int);/**/
voidDoOnce();/**/
voidConnectWeb(void);/**/
voidSendRequest(void);/**/
voidReceiveResponse(void);/**/
voidGetEmail(char*);/**/
voidGetLink(char*);/**/
voidGetBeforePos(char*,char**);/**/
voidGetAfterPos(char*,char**);/**/
voidAddChildNode(WEBNODE*,char*);/**/
voidGetAfterPosWithSlash(char*,char**);/**/
voidGetMemory(char**,int);/**/
intIsExistWeb(WEBNODE*,char*,char*,int,char*);/**/
voidRstrchr(char*,int,char**);/**/
intGetLocalAgent(char*UserAgent,char*Accept,char*AcceptLanguage,char*AcceptEncoding,char*AcceptCharset,char*KeepAlive,char*Connection,char*ContentType);/**/
/**************************************************************
功能:设置HTTP协议头内容的一些固定值
**************************************************************
*/
intGetLocalAgent(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));
return0;
}

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

/**************************************************************
功能:连接一个网站服务器
**************************************************************
*/
voidConnectWeb(void){/*connecttowebserver*/
/*createasocketdescriptor*/
if((sockfd=socket(PF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,
" SocketError:%sa ",strerror(errno));
exit(
1);
}

/*bindaddress*/
bzero(
&server_addr,sizeof(server_addr));
server_addr.sin_family
=AF_INET;
server_addr.sin_port
=htons(NodeCurr->port);
server_addr.sin_addr
=*((structin_addr*)host->h_addr);

/*connecttotheserver*/
if(connect(sockfd,(structsockaddr*)(&server_addr),sizeof(structsockaddr))==-1)
{
fprintf(stderr,
" ConnectError:%sa ",strerror(errno));
exit(
1);
}
}

/**************************************************************
功能:向网站发送HTTP请求
**************************************************************
*/
voidSendRequest(void){/*sendmyhttp-requesttowebserver*/
dsend
=0;totalsend=0;
nbytes
=strlen(request);
while(totalsend<nbytes){
dsend
=write(sockfd,request+totalsend,nbytes-totalsend);
if(dsend==-1){fprintf(stderr," senderror!%s ",strerror(errno));exit(0);}
totalsend
+=dsend;
fprintf(stdout,
" Request.%d%dbytessendOK! ",reqn,totalsend);
}
}

/**************************************************************
功能:接收网站的HTTP返回
**************************************************************
*/
voidReceiveResponse(void){/*getresponsefromwebserver*/
fd_setwritefds;
structtimevaltival;
intretry=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,socketisnegative! ");exit(0);}

ret
=select(sockfd+1,&writefds,NULL,NULL,&tival);
if(ret==0){
if(retry++<10)goto__ReCeive;
}
if(ret<=0){fprintf(stderr," Errorwhilereceiving! ");exit(0);}

if(FD_ISSET(sockfd,&writefds)){
memset(buffer,
0,1024);
memset(httpheader,
0,1024);
if((localfp=fopen(NodeCurr->file,"w"))==NULL){if(DEBUG)fprintf(stderr,"createfile'%s'error ",NodeCurr->file);return;}
/*receivedatafromwebserver*/
while((nbytes=read(sockfd,buffer,1))==1)
{
if(i<4){/*获取HTTP消息头*/
if(buffer[0]==' '||buffer[0]==' ')i++;
elsei=0;
memcpy(httpheader
+j,buffer,1);j++;
}
else{/*获取HTTP消息体*/
fprintf(localfp,
"%c",buffer[0]);/*printcontentonthescreen*/
//fprintf(stdout,"%c",buffer[0]);/*printcontentonthescreen*/
i++;
}
}
fclose(localfp);
}
}

/**************************************************************
功能:执行一次HTTP请求
**************************************************************
*/
voidDoOnce(){/*sendandreceive*/
ConnectWeb();
/*connecttothewebserver*/

/*sendarequest*/
SendRequest();

/*receivearesponsemessagefromwebserver*/
ReceiveResponse();

close(sockfd);
/*becauseHTTPprotocoldosomethingoneconnection,soIcancloseitafterreceiving*/
}

/**************************************************************
功能:执行HTTP请求
**************************************************************
*/
voidDoneWithList(intflag){
if(flag)fprintf(stdout," Request.%dis: %s",++reqn,request);

DoOnce();

if(flag)fprintf(stdout," Thefollowingistheresponseheader: %s",httpheader);
}

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

*port=0;
if(!(*src))return-1;
pA
=src;
if(!strncmp(pA,"http://",strlen("http://")))pA=src+strlen("http://");
/*elseif(!strncmp(pA,"https://",strlen("https://")))pA=src+strlen("https://");*/
elsereturn1;
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);
elselen=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;

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

intmain(intargc,char**argv)
{
intWebPort;
char*WebHost=0,*PageAddress=0,*WebDir=0;

if(argc<2){if(DEBUG)fprintf(stdout,"Commanderror,youshouldinputlikethis: %sWebPageAddress1WebPageAddress2WebPageAddress3...",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);/*Getwebpageinfo*/
if(ret){if(DEBUG)fprintf(stdout,"GetHosterrorfrom'%s' ",argv);exit(0);}
AddInitNode(WebHost,PageAddress,WebPort,WebDir);
/*addthispagetochain*/
}
free(WebHost);free(PageAddress);free(WebDir);
if(DEBUG){
fprintf(stdout,
" Display.%5d:",FileNumber);
DisplayNode(NodeHeader);
/*displayeverynode*/
}
HandleInitNode(NodeHeader);
/*handleeverypage*/
return0;
}
/**************************************************************
功能:分析网页
**************************************************************
*/
voidAnalyzePage(WEBNODE*node)
{
intfd;
intflength=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=color: #0000
分享到:
评论

相关推荐

    C 语言编写一个网络蜘蛛(网络爬虫)

    标题中的“C 语言编写一个网络蜘蛛(网络爬虫)”指的是使用C语言来实现一个网络爬虫程序,网络爬虫是一种自动遍历互联网并抓取网页内容的软件。网络爬虫通过模拟浏览器的行为,向服务器发送HTTP请求,获取响应,并...

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

    在本项目中,我们将探讨如何使用C语言编写一个网络蜘蛛,其主要任务是寻找并提取网页上的电子邮件地址。下面将详细介绍这个过程涉及的知识点。 首先,我们需要了解基本的网络编程概念,尤其是HTTP协议。C语言中可以...

    用C语言编写一个网络蜘蛛

    用C语言编写一个网络蜘蛛 本资源是一个使用C语言编写的网络蜘蛛程序,旨在从互联网上搜索特定的内容,如邮件地址。该程序可以不断地从网络上取得页面,然后分析出网页上出现的邮件地址保存下来。 知识点1: 网络...

    C 语言编写一个网络蜘蛛

    【C 语言编写一个网络蜘蛛】的描述中提到的网络蜘蛛是一个程序,它模拟网络爬虫的行为,遍历互联网上的网页,寻找特定的信息,如电子邮件地址。以下将详细阐述网络蜘蛛的基本概念、C 语言实现的关键技术和涉及的编程...

    一个简易的用C语言编写的蜘蛛纸牌小游戏

    【标题】中的“一个简易的用C语言编写的蜘蛛纸牌小游戏”表明我们要讨论的是一个使用C语言开发的蜘蛛纸牌游戏。蜘蛛纸牌是一种流行的单人纸牌游戏,通常在计算机上玩,这里它是通过编程语言C实现的。 【描述】的...

    C语言开发-经典游戏-像素蜘蛛纸牌

    在本项目中,我们探索的是使用C语言进行经典游戏——像素蜘蛛纸牌的开发。C语言是一种基础且高效的编程语言,常用于系统级编程、游戏开发以及嵌入式系统等。在这个项目中,开发者选择了DevC++ EGE图形库来实现游戏的...

    C(#)网络蜘蛛源码

    本源码是用C#语言编写的,它展示了如何利用C#进行网络爬虫的开发。 在C#中,实现网络蜘蛛的关键技术包括HTTP请求、HTML解析和数据存储。以下将详细解释这些知识点: 1. **HTTP请求**:网络蜘蛛首先需要通过HTTP...

    使用爬虫语言编写的项目源码

    这个名为“使用爬虫语言编写的项目源码”的资源很可能包含了一整套用特定编程语言实现的爬虫程序,用于自动化地从互联网上抓取和处理数据。在这个项目中,我们可以探讨几个关键的知识点: 1. **爬虫的基本概念**:...

    zhipai.rar_ZHIPAI_蜘蛛纸牌_蜘蛛纸牌C语言

    【标题】"zhipai.rar_ZHIPAI_蜘蛛纸牌_蜘蛛纸牌C语言" 提供了一个关于使用C语言开发蜘蛛纸牌游戏的信息。蜘蛛纸牌是一款流行的单人纸牌游戏,通常在计算机上玩,它涉及到策略和逻辑思考。在C语言中实现这个游戏是一...

    蜘蛛程序源码v1·0C开发

    但假设这里是指C#,那么这可能是另一个版本的蜘蛛程序,C#是微软开发的一种面向对象的编程语言,拥有丰富的库支持和.NET框架,更适合开发复杂的、具有图形用户界面的爬虫项目。C#中的System.Net和System.IO库为爬虫...

    matlab开发-使用imulinKandStateFlow创建一个机器人蜘蛛

    本教程将聚焦于如何利用这两个工具来创建一个机器人蜘蛛。MATLAB是MathWorks公司出品的一种高级编程语言,广泛应用于科学计算、数据分析以及工程设计领域。imulink则是一个图形化接口,用于建立动态系统的模型,而...

    搜索引擎技术揭密之搜索蜘蛛系列文摘

    C语言编写网络蜘蛛搜索网上出现的电子邮件地址.pdf可能是一份实践性的教程,讲解如何用C语言编写一个简单的爬虫,专门用于查找公开的电子邮件地址。这通常涉及到解析HTML,识别和提取邮件地址,以及可能的反垃圾邮件...

    C++蜘蛛纸牌小游戏

    在编写蜘蛛纸牌游戏时,C++的面向对象特性(如封装、继承和多态)使得代码组织清晰,易于维护。 游戏的核心部分涉及到数据结构和算法的设计。在这个项目中,可能会用到链表或者数组来表示牌堆、待整理区以及玩家的...

    c#蜘蛛、网络爬虫源代码

    标题中的“C#蜘蛛、网络爬虫源代码”是指使用C#编程语言编写的网络爬虫程序的源代码。网络爬虫,也称为网页抓取器或数据抓取工具,是一种自动化程序,它能遍历互联网上的网页,收集所需信息。在C#中实现爬虫,通常会...

    用Perl写的网络蜘蛛fetchgals-5.6

    "fetchgals-5.6" 是一个基于Perl编写的网络蜘蛛(Web Crawler)程序,它的主要功能是自动抓取互联网上的信息,例如网页内容、图片、链接等。网络蜘蛛在搜索引擎优化(SEO)、数据分析和网站维护等领域有着广泛的应用...

    用Python实现网络爬虫、蜘蛛.doc

    以下是一个简单的示例,使用`SGMLParser`类来提取网页正文: ```python from sgmllib import SGMLParser class Html2txt(SGMLParser): def reset(self): self.text = '' self.inbody = True SGMLParser....

    Spider社交蜘蛛优化.zip

    其中,"Spider.m"可能是用MATLAB编写的一个实现社交蜘蛛算法的脚本,而"social spider algorithm_2015.pdf"则可能是一个详细解释这种算法的学术论文或教程。 社交蜘蛛优化算法,顾名思义,是受到自然界中蜘蛛社会...

    蜘蛛纸牌VC++源代码最新之作

    【蜘蛛纸牌VC++源代码最新之作】是一个与编程相关的项目,主要集中在使用Microsoft的C++编译器(Visual C++,简称VC++)来实现经典的蜘蛛纸牌游戏。在这个项目中,开发者通过编写源代码,将游戏逻辑、用户界面以及...

    易语言编写蜘蛛模拟器

    易语言编写蜘蛛模拟器是指使用易语言编程语言编写的一个蜘蛛模拟器,模拟蜘蛛的行为来抓取网络资源。蜘蛛模拟器的主要作用是模拟蜘蛛对网站的访问,抓取网站上的资源,并将其存储起来以供后续使用。 易语言中的蜘蛛...

    用Python实现网络爬虫、蜘蛛.docx

    文档中还提到了一个使用Django框架、Python语言以及`BeautifulSoup`库组合实现的垂直搜索引擎爬虫。垂直搜索引擎爬虫通常针对特定领域的网站进行爬取。文档中提到了Django模型的创建以及爬虫代码的编写: 1. **...

Global site tag (gtag.js) - Google Analytics