用C语言编写一个网络蜘蛛
搜索引擎spider爬虫(蜘蛛)原理
![搜索引擎spider爬虫(蜘蛛)原理](https://img.taocdn.com/s3/m/66a4ea1c53ea551810a6f524ccbff121dd36c59c.png)
搜索引擎spider爬⾍(蜘蛛)原理做SEO的⼈应该要对搜索引擎的基本原理有⼀些了解,从搜索引擎发现⽹址到该页⾯拥有排名,以及后续更新整个过程中,搜索引擎到底是怎么⼯作的?你都需要了解。
对于专业的算法不必进⾏深⼊的研究,但是对于搜索引擎⼯作中的⽣命⼒和算法原理要有个简单的认知,这样才能更有效地开展SEO⼯作,知其然也要知其所以然;当然也有⼀些朋友不懂这些,照样做昨有声有⾊,但是有对搜索引擎⼯作原理,懂总⽐不懂好⼀点。
以往的SEO书藉中对这内容讲解都⽐较简单,希望在些能够尝试结合SEO实际⼯作和现象,更进⼀步剖析⼀下搜索引擎的⼯作原理,其实当你了解了搜索引擎的⼯作流程、策略和基本算法后,就可以在⼀定程序上避免因为不当操作⽽带来的不必要处罚,同也可以快速分析出很多搜索引擎搜索结果异常的原因。
有搜索⾏为的地⽅就有搜索引擎,站内搜索、全⽹搜索、垂直搜索等都⽤到搜索引擎;接下来,本⽂会根据从业认知,讨论⼀下全⽂搜索引擎的基本架构。
百度、⾕歌等综合搜索巨头肯定有着更为复杂的架构和检索技术,但宏观上基本原理都差不多的。
搜索引擎的⼤概架构如图2-1所⽰。
可以分成虚线左右两个部分:⼀部分是主动抓取⽹页进⾏⼀系列处理后建⽴索引,等待⽤户搜索;另⼀部分是分析⽤户搜索意图,展现⽤户所需要的搜索结果。
搜索引擎主动抓取⽹页,并进⾏内容处理、索引部分的流程和机制⼀般如下:1.派出spider按照⼀定策略把⽹页抓回到搜索引擎服务器;2.对抓回的⽹页进⾏链接抽离、内容处理,削除噪声、提取该页主题⽂本内容等;3.对⽹页的⽂本内容进⾏中⽂分词、去除停⽌词等;4.对⽹页内容进⾏分词后判断该页⾯内容与已索引⽹页是否有重复,剔除重复页,对剩余⽹页进⾏倒排索引,然后等待⽤户的检索。
当有⽤户进⾏查询后,搜索引擎⼯作的流程机制⼀般如下:1.先对⽤户所查询的关键词进⾏分词处理,并根据⽤户的地理位置和历史检索特征进⾏⽤户需求分析,以便使⽤地域性搜索结果和个性化搜索结果展⽰⽤户最需要的内容;2.查找缓存中是否有该关键词的查询结果,如果有,有为最快地呈现查询,搜索引擎会根据当下⽤户的各种信息判断其真正需求,对缓存中的结果进⾏微调或直接呈现给⽤户;3.如果⽤户所查询的关键词在缓存中不存在,那么就在索引库中的⽹页进⾏调取排名呈现,并将该关键词和对应的搜索结果加⼊到缓存中;4.⽹页排名是⽤户的搜索词和搜索需求,对索引库中⽹页进⾏相关性、重要性(链接权重分析)和⽤户体验的⾼低进⾏分析所得出的。
用C#实现网络爬虫
![用C#实现网络爬虫](https://img.taocdn.com/s3/m/e5febb95ec3a87c24128c401.png)
网络爬虫在信息检索与处理中有很大的作用,是收集网络信息的重要工具。
接下来就介绍一下爬虫的简单实现。
爬虫的工作流程如下爬虫自指定的URL地址开始下载网络资源,直到该地址和所有子地址的指定资源都下载完毕为止。
下面开始逐步分析爬虫的实现。
1. 待下载集合与已下载集合为了保存需要下载的URL,同时防止重复下载,我们需要分别用了两个集合来存放将要下载的URL和已经下载的URL。
因为在保存URL的同时需要保存与URL相关的一些其他信息,如深度,所以这里我采用了Dictionary来存放这些URL。
具体类型是Dictionary<string, int> 其中string是Url字符串,int是该Url相对于基URL的深度。
每次开始时都检查未下载的集合,如果已经为空,说明已经下载完毕;如果还有URL,那么就取出第一个URL加入到已下载的集合中,并且下载这个URL的资源。
2. HTTP请求和响应C#已经有封装好的HTTP请求和响应的类HttpWebRequest和HttpWebResponse,所以实现起来方便不少。
为了提高下载的效率,我们可以用多个请求并发的方式同时下载多个URL的资源,一种简单的做法是采用异步请求的方法。
控制并发的数量可以用如下方法实现1 private void DispatchWork()2 {3 if (_stop) //判断是否中止下载4 {5 return;6 }7 for (int i = 0; i < _reqCount; i++)8 {9 if (!_reqsBusy[i]) //判断此编号的工作实例是否空闲10 {11 RequestResource(i); //让此工作实例请求资源12 }13 }14 }由于没有显式开新线程,所以用一个工作实例来表示一个逻辑工作线程1 private bool[] _reqsBusy = null; //每个元素代表一个工作实例是否正在工作2 private int _reqCount = 4; //工作实例的数量每次一个工作实例完成工作,相应的_reqsBusy就设为false,并调用DispatchWork,那么DispatchWork就能给空闲的实例分配新任务了。
蜘蛛程序的名词解释
![蜘蛛程序的名词解释](https://img.taocdn.com/s3/m/465f74af0875f46527d3240c844769eae109a35f.png)
蜘蛛程序的名词解释蜘蛛程序(spider)是一种自动化程序,通常由搜索引擎和网站监测工具使用,用于在互联网上扫描和收集信息。
它的工作原理类似于蜘蛛在网上爬行并收集食物,因此得名为“蜘蛛程序”。
蜘蛛程序利用互联网的链接结构进行信息的搜集和分析。
它会从一个初始的网页开始,通过链接跳转到其他网页,并抓取这些页面上的内容。
这些内容包括文字、图片、视频和其他多媒体文件。
蜘蛛程序通过解析HTML代码来获取网页的内容,并将其保存在搜索引擎的数据库中。
蜘蛛程序的任务是将互联网上的信息整理、分类和索引,以便于搜索引擎能够对其进行搜索和检索。
它们通过收集大量的网页和文件,建立起复杂的链接网络,从而能够帮助用户找到他们感兴趣的内容。
搜索引擎蜘蛛程序向用户提供了一个简便而高效的搜索工具,使得用户能够迅速地找到所需的信息。
蜘蛛程序具有高度自动化的特点。
它们能够在互联网上自动地跳转、抓取和解析网页内容,并且能够定期更新已经抓取的网页。
这使得搜索引擎能够提供最新的搜索结果,并及时更新网页的相关信息。
然而,蜘蛛程序也面临一些挑战和限制。
首先,互联网上的信息量巨大,蜘蛛程序需要不断地抓取和解析大量的网页。
这需要庞大的计算和存储资源,以及高效的算法和技术支持。
其次,蜘蛛程序需要面对复杂的网页结构和页面设计,包括AJAX、Flash等技术的应用。
这些技术使得网页的内容不容易被蜘蛛程序所抓取和解析。
此外,有些网站会采取一些特殊的技术手段,如robots.txt文件、META标签等,来限制蜘蛛程序的访问。
为了应对这些挑战,蜘蛛程序需要不断地进行技术改进和优化。
搜索引擎公司投入了大量的研发资源,来提高蜘蛛程序的效率和准确性。
他们开发了各种算法和技术,如链接分析算法、页面排名算法等,来优化蜘蛛程序的工作。
同时,他们也与网站管理员合作,共同制定规范和标准,以便更好地管理蜘蛛程序的访问。
总之,蜘蛛程序作为搜索引擎的基础技术之一,在互联网信息检索中起到了重要的作用。
Java 多线程 爬虫程序(spider)设计与实现
![Java 多线程 爬虫程序(spider)设计与实现](https://img.taocdn.com/s3/m/18e1507401f69e31433294e9.png)
Java 多线程爬虫程序(spider)设计与实现2009年04月15日星期三19:01转自:《福建电脑》吴小竹当spider程序访问到一个网页,必须进行以下几项基本处理:抽取网页中包含的文本;抽取网页中包含的URL,并将其区分为网页中包含的文本;抽取网页中包含的URL,并将其区分为网站内URL或网站外URL。
2.2各主要功能模块(类)设计2.2.1 spider类该类为主类,继承自线程类。
它本事并不做获取网页的具体工作,而是协调其他各类共同完成任务。
其主要类成员及方法如下:2.2.2 spiderworker类该类继承线程类,进行获取网页,抽取文本,URL等实际工作。
2.2.3 urlmanager类该类管理所获得的各种URL,利用四种URL队列来管理。
等待队列:等待刚问的URL队列,队列中的URL一经访问完便进入完成队列或不可达URL队列。
运行队列:正在访问的URL队列;完成队列:已访问过的URL队列;不可达队列:不可达的URL队列,即该URL对应的文件不可访问。
2.2.4 spiderwatcher类该类用来监视各线程的运行情况数,能确定实时的活动线程数。
2.3 SPIDER 工作过程a 给spider程序赋予一个初始URL,加入URL等待队列。
b根据需要确定线程池大小,启动n个线程。
c查询等待队列中是否有URL,若没有,且无其他活动线程序,线程结束;若有转d。
d从URL等待队列中取出一个URL,并移入运行对流,根据该URL去访问,并进行网页下载,抽取文本,抽取链接等工作。
若网页中包含URL,则把这些URL加入等待队列;吧访问过的URL加入完成队列,转c3.1 java中线程的生命周期java的线程从产生到消失,可分为四个状态:a 新建状态:线程在已被创建但尚未执行这段时间内,处于新建状态。
此时,线程对象已被分配内存空间,起私有数据已被初始化,但没有给其分配系统资源且线程未被调度。
处于此状态的线程,可以通过调用start()或stop()函数来开始线程或终止线程。
Python网络爬虫技术 第1章 Python爬虫环境与爬虫介绍
![Python网络爬虫技术 第1章 Python爬虫环境与爬虫介绍](https://img.taocdn.com/s3/m/ef40c53f366baf1ffc4ffe4733687e21af45ffc2.png)
大数据挖掘专家
30
配置MySQL数据库
1. Windows下MySQL配置
➢ 设置MySQL的环境变量:第二种设置环境变量的方法。 • 直接在“Path”变量中添加“C:\Program Files\MySQL\MySQL Server 5.6\bin”。
大数据挖掘专家
31
配置MySQL数据库
1. Windows下MySQL配置
4
小结
大数据挖掘专家
17
Python爬虫相关库介绍与配置
Python爬虫相关库
目前Python有着形形色色的爬虫相关库,按照库的功能,整理如下。
类型
通用
框架 HTML/XML
解析器
库名
简介
urllib
Python内置的HTTP请求库,提供一系列用于操作URL的功能
requests
基于urllib,采用Apache2 Licensed开源协议的HTTP库
离,距离越近的页面中的链接优先访问。
大数据挖掘专家
5
爬虫的原理
3. 增量式网络爬虫
增量式网络爬虫只对已下载网页采取增量式更新或只爬行新产生的及已经发生变化的网页,需要通过重新访 问网页对本地页面进行更新,从而保持本地集中存储的页面为最新页面。 常用的更新方法如下。 ➢ 统一更新法:以相同的频率访问所有网页,不受网页本身的改变频率的影响。 ➢ 个体更新法:根据个体网页的改变频率来决定重新访问各页面的频率。 ➢ 基于分类的更新法:爬虫按照网页变化频率分为更新较快和更新较慢的网页类别,分别设定不同的频率来
访问这两类网页。
大数据挖掘专家
6
爬虫的原理
4. 深层网络爬虫
Web页面按照存在方式可以分为表层页面和深层页面两类。表层页面指以传统搜索引擎可以索引到的页面,深 层页面为大部分内容无法通过静态链接获取,隐藏在搜索表单后的,需要用户提交关键词后才能获得的Web页 面。 深层爬虫的核心部分为表单填写,包含以下两种类型。 ➢ 基于领域知识的表单填写:该种方法一般会维持一个本体库,通过语义分析来选取合适的关键词填写表单。 ➢ 基于网页结构分析的表单填写:这种方法一般无领域知识或仅有有限的领域知识,将HTML网页表示为DOM
有趣的c语言代码例子
![有趣的c语言代码例子](https://img.taocdn.com/s3/m/f6d6355630b765ce0508763231126edb6f1a76a6.png)
有趣的c语言代码例子
1.猜数字游戏:编写程序生成一个介于1到100之间的随机数,用户输入猜测的数字直到猜对为止,程序会给出猜测数字相对于答案的大小关系提示(例如“猜测数字太大”或“猜测数字太小”)。
2. 打地鼠游戏:在屏幕上生成随机的地鼠图案,用户用鼠标点击击打地鼠以获得分数,随着时间的推移地鼠速度逐渐加快。
3. 贪吃蛇游戏:编写程序生成一个贪吃蛇,蛇头可以用键盘控制移动,当蛇吃到食物时身体长度增加,当蛇头碰到墙壁或自己的身体时游戏结束。
4. 数独游戏:生成一个数独谜题,用户通过键盘输入数字来填充空白格子,当谜题填写完整且符合数独规则时游戏结束。
5. 神经网络:使用C语言实现一个简单的神经网络,可以用来识别手写数字或其他模式识别任务。
6. 数据结构:实现一个栈或队列数据结构,可以用来解决各种实际问题。
7. 图像处理:使用C语言读取图像文件并进行简单的处理,例如灰度化、边缘检测或图像滤波等。
8. 加密解密:实现一个简单的加密解密算法,例如Caesar密码或RSA加密算法。
9. 排序算法:实现常见的排序算法,例如冒泡排序、插入排序或快速排序等。
10. 计算机模拟:使用C语言模拟各种实际问题,例如天气预报、
股票交易或人口统计等。
C语言网络编程详解
![C语言网络编程详解](https://img.taocdn.com/s3/m/5f8c07d26aec0975f46527d3240c844768eaa047.png)
C语言网络编程详解网络编程是计算机科学中的重要领域,而C语言作为一种广泛使用的编程语言,也在网络编程中扮演着重要的角色。
本文将详细介绍C 语言网络编程的相关知识和技巧,帮助读者更好地理解和应用该领域的知识。
1. 网络编程概述网络编程是指利用计算机网络进行程序开发和通信的过程。
它主要涉及到数据传输、网络协议、套接字等概念。
C语言提供了一系列函数和库来支持网络编程,如socket函数、bind函数、listen函数等。
2. 套接字编程套接字(socket)是进行网络通信的一种机制。
C语言提供了一组函数用于创建、设置和管理套接字。
通过使用这些函数,我们可以建立起客户端和服务器之间的通信连接,实现数据的收发和传输。
2.1 套接字基础在进行网络编程之前,我们需要了解基本的套接字概念和操作。
首先,我们需要创建一个套接字,可以是TCP套接字或者UDP套接字。
然后,我们可以使用bind函数将套接字与IP地址和端口号绑定。
接下来,我们可以使用listen函数开始监听来自客户端的连接请求。
2.2 TCP编程TCP(传输控制协议)是一种可靠的连接协议,适用于需要保证数据可靠传输的场景。
在C语言中,我们可以使用socket函数创建一个TCP套接字。
然后,通过accept函数接受来自客户端的连接请求,使用send和recv函数进行数据的发送和接收。
2.3 UDP编程UDP(用户数据报协议)是一种无连接的协议,适用于需要快速传输数据的场景。
在C语言中,我们可以使用socket函数创建一个UDP 套接字。
与TCP不同的是,UDP不需要先建立连接,可以直接使用sendto和recvfrom函数进行数据的发送和接收。
3. 网络编程实例为了更好地理解和应用C语言网络编程,下面将通过两个实例来演示TCP和UDP编程的基本过程。
3.1 TCP编程实例假设我们要实现一个简单的聊天室程序,服务器接收来自不同客户端的消息,并转发给其他客户端。
蜘蛛程序的名词解释是
![蜘蛛程序的名词解释是](https://img.taocdn.com/s3/m/dc574ef9970590c69ec3d5bbfd0a79563c1ed4ee.png)
蜘蛛程序的名词解释是蜘蛛程序的名词解释是“网络爬虫”网络爬虫,又称为蜘蛛程序、网络机器人,是一种能够自动浏览互联网信息的计算机程序。
它们为搜索引擎和其他应用程序收集网页,并将这些网页内容保存在数据库中,以便后续使用和分析。
网络爬虫的工作原理类似于现实生活中的蜘蛛。
它们从一个起始点(通常是一个特定的网页)开始,根据预设的规则和策略,沿着网页之间的链接不断爬行,将访问到的网页内容保存下来。
这些链接可以是超链接,也可以是表单提交等方式。
通过这种方式,网络爬虫可以覆盖并获取大量的网页信息。
网络爬虫的应用广泛,其中最常见的应用就是搜索引擎。
搜索引擎通过网络爬虫收集尽可能多的网页,然后对这些网页进行处理和索引,以便用户能够方便地找到所需的信息。
网络爬虫通过分析网页的标题、内容、链接等信息,搜索引擎可以建立起一个庞大的网页索引库,为用户提供准确、全面的搜索结果。
除了搜索引擎,网络爬虫还被广泛应用于数据挖掘和其他领域的研究中。
通过爬取互联网上的大量数据,研究人员可以对数据进行分析和挖掘,从中发现有价值的信息和规律。
例如,在市场调研中,研究人员可以爬取相关行业的网页数据来了解市场动态和竞争对手的情况。
在金融领域,网络爬虫可以帮助投资者获取最新的股票数据,并进行分析和预测。
然而,网络爬虫也面临着一些挑战和限制。
首先,由于互联网上的信息量庞大,网络爬虫可能无法有效地覆盖所有的网页。
其次,有些网站会设置反爬虫机制,限制爬虫程序的访问,并对其进行识别和封锁。
此外,网络爬虫在访问网页时需要消耗大量的带宽和计算资源,对服务器造成一定的负担,因此应该遵守相关的爬虫规范和道德准则。
为了提高网络爬虫的效率和准确性,研究人员不断提出新的算法和技术。
例如,基于机器学习和自然语言处理的技术可以帮助爬虫程序更好地理解和解析网页内容,从而提高数据的质量。
此外,分布式爬虫系统可以同时运行多个爬虫程序,从而加快数据的收集和处理速度。
总的来说,网络爬虫是一种能够自动浏览互联网信息的计算机程序。
C#网络编程教程
![C#网络编程教程](https://img.taocdn.com/s3/m/6495ca29bd64783e09122b32.png)
5
C#
第 5.1 TCP/IP概述 5 章 5.1.1 OSI参考模型与TCP/IP模型 网 络 编 程 方 法 概 述
(4)传输层(Transport Layer) 传输层的任务是根据通信子网的特性来最佳地利用网络资源,并以可靠 和经济的方式,为两个端系统(也就是源站和目的站)的会话层之间,提供 建立、维护和取消传输连接的功能,并负责可靠地传输数据。在这一层,信 息的传送单位是报文。 (5)会话层(Session Layer) 会话层也称为会晤层或对话层,在会话层及以上的高层次中,数据传送 的单位不再另外命名,都统称为报文。会话层不参与具体的传输,它提供包 括访问验证和会话管理在内的建立和维护应用之间通信的机制。如服务器验 证用户登录便是由会话层完成的。 (6)表示层(Presentation Layer) 表示层主要解决用户信息的语法表示问题。它将欲交换的数据从适合于 某一用户的抽象语法,转换为适合于OSI系统内部使用的传送语法。即提供 格式化的表示和转换数据服务。数据的压缩和解压缩,加密和解密等工作都 由表示层负责。
9
图5.2 OSI参考模型与TCP/IP模型对比
图5.3 TCP/IP协议族
第 5.1 TCP/IP概述 5 章 5.1.1 OSI参考模型与TCP/IP模型 (1)链路层 C# 网 络 编 程 方 法 概 述
10
链路层是TCP/IP协议族的最低层,有时也被称作数据链路层或网络接口 层,通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡,它 们一起处理与电缆(或其他任何传输媒体)的物理接口。该层负责接收IP数 据报并通过网络发送到网络传输媒体上,或者从网络上接收物理帧,抽出IP 数据报交给IP层。实际上,TCP/IP模型并没有真正描述这一层的实现,只是 要求能够提供给其上层(网络层)一个访问接口,以便在其上传递IP分组。 由于这一层次未被定义,所以其具体的实现方法也随着网络类型的不同而不 同。 (2)网络层 网络层是整个TCP/IP协议栈的核心,有时也被称为互联网层或IP层。该 层的主要功能是把分组发往目标网络或主机。同时,为了尽快发送分组,可 能需要沿不同的路径同时进行分组传递。因此,分组到达的顺序和发送的顺 序可能不同,这就需要上层对分组进行排序。网络层除了完成上述功能外, 还完成将不同类型的网络(异构网)进行互连的功能。除此之外,网络层还 需要完成拥塞控制的功能。 在TCP/IP协议族中,网络层协议包括IP协议(网际协议)、ICMP协议( 因特网控制报文协议)和IGMP协议(因特网组管理协议)。
有趣的c语言代码
![有趣的c语言代码](https://img.taocdn.com/s3/m/4c104d340640be1e650e52ea551810a6f524c816.png)
有趣的c语言代码在计算机编程领域中,C语言无疑是居于重要地位的一种语言。
它简洁明了,具有高度的灵活性,其语法规范和基本结构也有着非常强的适用性,依旧是很多应用领域的首选语言。
但是,除了作为一门实用的编程语言外,C语言也具备着不少有趣的面向场景和实现思路。
有时候我们不妨放开心态,花一点时间去探索一些优美、神奇或者古怪的代码,或许不仅可以带来好玩的游戏体验,还可以深刻领略计算机编程这一领域的魅力所在。
以下是几个有趣的C语言代码:1. Hello World!这是许多人接触编程时会碰到的第一行代码,既简单又经典。
用C 语言实现只需一行:include <stdio.h>int main(){printf("Hello, World!");return 0;}这段代码的功能很简单,输出 "Hello, World!"。
2. 回文字检测给定一个字符串,判断其是否为回文字符串。
这也是许多入门程序员接触的练手题。
bool isPalindrome(char *s){int len = strlen(s);for (int i = 0; i < len / 2; ++i)if (s[i] != s[len - 1 - i])return false;return true;}这段代码通过比较字符串中左右两端字符是否相同,完成回文检测。
3. 汉诺塔游戏汉诺塔是一个经典的数学谜题,至今仍是计算机课程和聚会游戏的热门选择之一。
在C语言中实现汉诺塔游戏的代码不仅具备实用价值,同时也挑战了程序设计师的算法思考能力。
void hanoi(int n, char A, char B, char C){if (n == 1)printf("%c -> %c\n", A, C);else{hanoi(n - 1, A, C, B);hanoi(1, A, B, C);hanoi(n - 1, B, A, C);}}这段代码通过递归实现了汉诺塔游戏的具体操作,将汉诺塔复杂的问题转化为简单的递归关系。
25编程器源码
![25编程器源码](https://img.taocdn.com/s3/m/87f9d699dc3383c4bb4cf7ec4afe04a1b071b083.png)
25编程器源码在这篇文章中,我们将分享25个有趣的编程器源码。
这些源码范围从简单的Hello World程序到复杂的算法和数据结构实现。
无论你是初学者还是有经验的开发者,这些源码都能帮助你提高你的编程技能。
1. Hello World:这是每个编程新手的必备源码。
它打印出'Hello World!',向你展示了如何输出一条简单的消息。
2. 计算器:这个源码将帮助你创建一个简单的计算器,让用户输入数字和运算符,并计算结果。
3. 猜数字游戏:这个源码使用随机数生成一个数字,并要求玩家猜这个数字是多少。
它通过循环和条件语句来实现。
4. 贪吃蛇游戏:这个源码将帮助你创建一个经典的贪吃蛇游戏。
它使用图形库来实现游戏界面,并通过键盘输入来控制蛇的移动。
5. 排序算法:这个源码实现了几种常见的排序算法,如冒泡排序、插入排序和快速排序。
它展示了如何在数组中排序元素。
6. 搜索算法:这个源码实现了几种常见的搜索算法,如线性搜索、二分搜索和广度优先搜索。
它展示了如何在数组或图中查找特定的元素。
7. 文件压缩器:这个源码实现了一个简单的文件压缩算法,可以将文件压缩成较小的文件,并可以解压缩回原始的文件。
8. 文本编辑器:这个源码将帮助你创建一个基本的文本编辑器,可以打开、编辑和保存文本文件。
9. 图像处理器:这个源码实现了一些基本的图像处理算法,如灰度化、边缘检测和图像模糊。
它展示了如何处理图像文件。
10. 网络爬虫:这个源码实现了一个简单的网络爬虫,可以从网页中提取数据并保存到文件中。
11. 邮件客户端:这个源码帮助你创建一个基本的邮件客户端,可以发送和接收邮件。
12. 网站登陆系统:这个源码实现了一个简单的网站登陆系统,可以验证用户的用户名和密码,并授予相应的权限。
13. 日历应用:这个源码将帮助你创建一个简单的日历应用,可以添加、编辑和删除事件。
14. 聊天应用:这个源码实现了一个简单的聊天应用,可以让用户之间进行实时的消息传递。
贪吃蛇(C语言)
![贪吃蛇(C语言)](https://img.taocdn.com/s3/m/9a659040a55177232f60ddccda38376baf1fe029.png)
贪吃蛇(C语言)#include#include#include#include#include//蛇头移动方向#define UP 1#define DOWN 2#define LEFT 3#define RIGHT 4〃死亡判定(葱墙或葱自己)#define KISSASS 1#define KISSWALL 2//坐标转化#define POINT(x,y) ((y)*80+(x)+1)// 将(x,y)坐标转化为一个int 类数值#define GETX(x) (((x)-1)%80)// 将int 类数值提取出原先的x#define GETY(y) (((y)-1)/80)// 同理,提取出yHANDLE Console;void Position(int x, int y); // 移动光标到(x,y) //Windows.hvoid DrawMap();// 画墙void ShowText(char *text);//根据字符串的长短智能打印出包围字符串的笑脸void ResetSnake();// 初始化贪吃蛇int RefreshSnake();// 更新蛇的移动void CreatFood();// 生成食物void Draw();//画出蛇身和食物void RefreshScreen();// 屏幕刷新void GameOver(int Type);// 游戏结束条件int Gaming();//代码跑起来char play = 0; ////值为1则继续游戏,值为0游戏退出char pause = 0; //值为1则暂停,值为0游戏继续char direction; // 蛇头方向int snake[500]; //snake[0]为蛇头int body; //蛇身体长度int newbody;//吃完食物新长的蛇身int addHead,deleteTail;//增加蛇头擦去蛇尾,使贪吃蛇动起来int food = 0; // 食物void main()(CONSOLE_CURSOR_INFO CurrInfo = { sizeof(CONSOLE_CURSOR_INFO), 0 };Console = GetStdHandle(STD_OUTPUT_HANDLE);DrawMap();ShowT ext("Copyright reserve by 博元");while(Gaming()){if (play)DrawMap();};return 0;}void Position(int x, int y)// 移动光标到(x,y) //Windows.h{COORD coors = { x, y };SetConsoleCursorPosition(Console, coors);}void DrawMap() // 画墙{int i;for (i = 3; i < 70; i = i + 12){Position(i, 0);printf("===我是墙===");}for (i = 0; i < 25; i = i + 1){Position(0, i);printf("|| ");}for (i = 3; i < 70; i = i + 12){Position(i, 24);printf("============");}for (i = 0; i < 25; i = i + 1){Position(76, i); printf("|| ");void ShowText(char *text) //根据字符串的长短智能打印出包围字符串的笑脸(int i;int strLength = strlen(text); // 得到字符串长度Position(40 - (strLength / 2)-1, 11);printf("%c”, 1);for (i = 0; i < strLength + 2; i++)(printf("%c", 1);}printf("%c", 1);Position(40 - (strLength / 2)-1, 12);printf("%c ", 1);printf(text);printf(" %c", 1);Position(40 - (strLength / 2)-1, 13);printf("%c", 1);for (i = 0; i < strLength + 2; i++)(printf("%c", 1);}printf("%c", 1);}void ResetSnake() //初始化贪吃蛇(int x, y;for (x = 39, y = 0; y < 2; y++)(snake[y] = POINT(x, 7 - y);}body = 2; //设定蛇身初始长度为2newbody = 6;addHead = 0;deleteTail = 0;direction = LEFT;}int RefreshSnake() 〃更新蛇的移动〃返回值为1游戏结束( int x, y;memcpy(snake + 1, snake, sizeof(int)*body);if (!newbody){deleteTail = snake[body];snake[body] = 0;}else{body++;newbody--;}x = GETX(snake[0]);y = GETY(snake[0]);switch (direction) //控制蛇头移动方向{case UP:y -= 1; //蛇头向上移动一格(对应坐标y-1 ) snake[0] = POINT(x, y);break;case DOWN:y += 1;snake[0] = POINT(x, y); break;case LEFT:x -= 1;snake[0] = POINT(x, y); break;case RIGHT:x += 1;snake[0] = POINT(x, y); break;}addHead = snake[0];if (x > 75 || x < 3 ||y > 23 || y < 1) // 检测是否撞墙(GameOver(KISSWALL);return 1;}int i;for (i = 1; i < body; i++)if (snake[0] == snake[i]) // 检测是否撞到自己身体(GameOver(KISSASS);return 1;}if (snake[0] == food)(while (1) //食物的位置不与蛇身重合(food = (rand() % (75 * 23));for (i = 0; snake[i]; i++)if (food == snake[i])// 检测是否吃到食物,吃到则reset食物food = 0;if (food) 〃如果food==0 则重新建立一个食物坐标break;}CreatFood(); // 吃了?再来一个!newbody = (rand() % 6) + 1; // 吃完食物蛇身增长一节}return 0;}void CreatFood() // 生成食物(if (GETX(food) > 75 || GETX(food) < 3 || GETY(food) > 23 || GETY(food) < 1) CreatFood;elsePosition(GETX(food), GETY(food));printf("%c”,4);}void Draw() //画出蛇身和食物(system("cls");int i;for (i = 0; snake[i]; i++)(Position(GETX(snake[i]), GETY(snake[i])); printf("%c”,1);}CreatFood();}void RefreshScreen() // 屏幕刷新(if (deleteTail)(Position(GETX(deleteTail), GETY(deleteTail)); printf("");}if (addHead)(Position(GETX(addHead), GETY(addHead)); printf("%c",1);}addHead = deleteTail = 0;}void GameOver(int Type) // 游戏结束条件(switch (Type)(case KISSASS://? 至ij 自己身体ShowT ext("NOOB !当你以光速绕着一棵树奔跑就会发现自己在葱自己!");break;case KISSWALL://撞墙ShowT ext("NOOB !你有考虑过墙的感受吗");}food = 0;play = 0;memset(snake, 0, sizeof(int) * 500); // 存初始化} int Gaming() // 执行int Keyboardinput;Sleep(60);// 速度if (kbhit())(Keyboardinput = getch();if (Keyboardi nput == 0 || Keyboardinput == 0xE0) (Keyboardinput = getch();switch (Keyboardi nput) // 方向控制(case 72:if (direction != DOWN) direction = UP;break;case 80:if (direction != UP)direction = DOWN;break;case 75:if (direction != RiGHT)direction = LEFT;break;case 77:if (direction != LEFT)direction = RiGHT;break;}}if (Keyboardi nput == '\r') // 暂停(if (!play)(play = 1;if (pause)(Draw();pause = 0;}}else(ShowT ext("不许暂停,继续葱!!");play = 0;pause =1;}}else if (KeyboardI nput == 0x1B) // 退出return 0; } if (play)(if (!food)(srand(clock());food = (rand() % (75 * 23)); ResetSnake();Draw();}else(if (!RefreshSnake())(RefreshScreen();}}}。
c语言经典游戏代码
![c语言经典游戏代码](https://img.taocdn.com/s3/m/ebdd9c7549d7c1c708a1284ac850ad02de80079d.png)
c语⾔经典游戏代码C语⾔精品游戏主⾓和怪物源码//C语⾔多线程-主⾓和怪物#include#include#define bool int //定义int变量为bool变量,bool不是真就是假int a=0,b=20;//主⾓的坐标int x=1,y=0;//怪物的坐标int i=1;//i值为真HANDLE hMutex;//1.坐标void GamePosition(HANDLE g_hout,int x,int y){COORD pos;//点的结构体pos.X=x;//横坐标pos.Y=y;//纵坐标SetConsoleCursorPosition(g_hout,pos);//设置控制平台光标位置}DWORD WINAPI Func(LPVOID lpParamter)//多线程的功能函数6.线程是画怪物{HANDLE hout=GetStdHandle(STD_OUTPUT_HANDLE);//7.拿到这张纸WaitForSingleObject(hMutex, INFINITE);//13.⾃⼰进来,⾃⼰⽤洗⼿间GamePosition(hout,x,y),printf('●');//8.在纸上画怪物ReleaseMutex(hMutex);//14.放弃使⽤权while(1)//9.怪物在横坐标为从0-10依次循环移动{if(x>=0&&i==1){printf(' ');GamePosition(hout,++x,y);printf('●');Sleep(1000);if(x==10)}else if(x<>{printf(' ');GamePosition(hout,--x,y);printf('●');Sleep(1000);if(x==0)i=1;}}return 0;}int main(){HANDLE hThread = CreateThread(NULL, 0, Func, NULL, 0, NULL);//5.创建线程hMutex = CreateMutexA(NULL, FALSE, '123');//创建互斥锁(量)//10.关上洗⼿间HANDLE hout=GetStdHandle(STD_OUTPUT_HANDLE);//2.拿到这张纸WaitForSingleObject(hMutex, INFINITE);//11.等待你的同事出来 15步接着GamePosition(hout,a,b),printf('☆');//3.在纸上画主⾓ReleaseMutex(hMutex);//12.同事出来了,放弃了洗⼿间的使⽤权while(1){if(kbhit())switch(getch())//控制左右 4.主⾓上下左右移动{case 'w':case 'W':if(b>3)GamePosition(hout,a,b),printf(' '),GamePosition(hout,a,--b),printf('☆'); break;case 's':case 'S':if(b<20)gameposition(hout,a,b),printf('>break;col = rand() % 10;if(map[row][col] == '0'){map[row][col] = 'x';num++;}}while(num <>for (row = 0;row <=>for (col = 0;col <=>if(map[row][col] != 'x'){int cnt = 0;for (num = 0;num <=>if(row + delta[num][0] <>continue;}if(row + delta[num][0] > 9){continue;}if(col + delta[num][1] <>continue;}if(col + delta[num][1] > 9){continue;}if(map[row + delta[num][0]][col + delta[num][1]]== 'x'){ cnt++;}}map[row][col] = '0' + cnt;}}}for (row = 0;row <>for(col = 0;col < 10;col="">printf('* ');}num = 0;int x,y;do{printf('please enter the coordinate of array:'); scanf('%d%d',&x,&y);show[x-1][y-1] = 1;if(map[x-1][y-1] == '0'){for (num = 0;num <=>if(x-1 + delta[num][0] <>continue;}if(x-1 + delta[num][0] > 9){continue;}if(y -1+ delta[num][1] <>continue;}if(y-1 + delta[num][1] > 9){continue;}show[x-1+delta[num][0]][y-1+delta[num][1]] = 1; }}if (map[x-1][y-1]!= 'x'&&map[x-1][y-1] != '0'){for (num = 0;num <=>int cnt = 0;if(x-1 + delta[num][0] <>continue;}if(x-1 + delta[num][0] > 9){continue;}if(y-1 + delta[num][1] <>if(y-1 + delta[num][1] > 9){continue;}if( map[x -1 + delta[num][0]][y -1+ delta[num][1]] != 'x'){ show[x-1 + delta[num][0]][y -1+ delta[num][1]] = 1 ; }}}if(map[x-1][y-1] == 'x') {printf('game over!\n');for (row = 0;row <>for(col = 0;col < 10;col="">printf('%c ',map[row][col]);}printf('\n');}return 0;}system('cls');printf('mine sweeping:\n');for (row = 0;row <>for(col = 0;col < 10;col="">if (show[row][col] == 1){printf('%c ', map[row][col]);}else{printf('* ');}}printf('\n');}for (row = 0;row <>for(col = 0;col < 10;col=""> if (show[row][col] == 1 ){num++;}}}printf('num:%d\n',num);}while(num <>printf('you win!');return 0;}。
网络爬行蜘蛛定义及原理讲解
![网络爬行蜘蛛定义及原理讲解](https://img.taocdn.com/s3/m/b3f31f24ed630b1c59eeb524.png)
网络爬行蜘蛛定义及原理讲解当“蜘蛛”程序出现时,现代意义上的搜索引擎才初露端倪。
它实际上是一种电脑“机器人”(Computer Robot),电脑“机器人”是指某个能以人类无法达到的速度不间断地执行某项任务的软件程序。
由于专门用于检索信息的“机器人”程序就象蜘蛛一样在网络间爬来爬去,反反复复,不知疲倦。
所以,搜索引擎的“机器人”程序就被称为“蜘蛛”程序。
网络蜘蛛什么是网络蜘蛛呢?网络蜘蛛即Web Spider,是一个很形象的名字。
把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛。
网络蜘蛛是通过网页的链接地址来寻找网页,从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止。
如果把整个互联网当成一个网站,那么网络蜘蛛就可以用这个原理把互联网上所有的网页都抓取下来。
这样看来,网络蜘蛛就是一个爬行程序,一个抓取网页的程序。
起源发展要说网络蜘蛛的起源,我们还得从搜索引擎说起,什么是搜索引擎呢?搜索引擎的起源是什么,这和网络蜘蛛的起源密切相关。
搜索引擎指自动从英特网搜集信息,经过一定整理以后,提供给用户进行查询的系统。
英特网上的信息浩瀚万千,而且毫无秩序,所有的信息象汪洋上的一个个小岛,网页链接是这些小岛之间纵横交错的桥梁,而搜索引擎,则为你绘制一幅一目了然的信息地图,供你随时查阅。
搜索引擎从1990年原型初显,到现在成为人们生活中必不可少的一部分,它经历了太多技术和观念的变革。
十四年前1994年的一月份,第一个既可搜索又可浏览的分类目录EINetGalaxy上线了。
在它之后才出现了雅虎,直至我们现在熟知的Google、百度。
但是他们都不是第一个吃搜索引擎这个螃蟹的第一人。
从搜索FTP上的文件开始,搜索引擎的原型就出现了,那时还未有万维网,当时人们先用手工后用蜘蛛程序搜索网页,但随着互联网的不断壮大,怎样能够搜集到的网页数量更多、时间更短成为了当时的难点和重点,成为人们研究的重点。
C语言中的网络编程基础
![C语言中的网络编程基础](https://img.taocdn.com/s3/m/c28c3b9077a20029bd64783e0912a21614797f1e.png)
C语言中的网络编程基础在计算机科学领域中,网络编程是一个非常重要的概念。
通过网络编程,我们可以实现计算机之间的通信和数据交换。
C语言是一种非常流行的编程语言,也可以用于网络编程。
本文将介绍C语言中的网络编程基础知识,帮助读者了解如何使用C语言进行网络编程。
一、网络编程概述网络编程是指使用计算机网络进行通信的编程技术。
它涉及到客户端和服务器之间的通信和数据传输。
在C语言中,我们可以使用一些库函数来实现网络编程,其中最常用的就是socket函数。
二、Socket编程Socket编程是网络编程的基础。
在C语言中,Socket是一个抽象的概念,代表了一个网络链接的端点。
使用Socket可以在客户端和服务器之间建立通信连接,并进行数据的传输。
要使用Socket进行网络编程,首先需要创建Socket。
在C语言中,可以使用socket函数来创建Socket。
该函数的原型如下:int socket(int domain, int type, int protocol);这个函数接受三个参数:domain表示协议域,type表示套接字类型,protocol表示具体的协议。
协议域(Domain)可以是AF_INET(IPv4协议)或AF_INET6(IPv6协议)。
套接字类型(Type)可以是SOCK_STREAM(流式套接字,用于建立可靠的连接)或SOCK_DGRAM(数据报套接字,用于无连接的通信)。
协议(Protocol)可以是0,表示根据套接字类型和协议域自动选择合适的协议。
创建Socket后,可以使用其他函数来对Socket进行配置和使用。
例如,可以使用bind函数将Socket与本地地址绑定,使用listen函数监听连接请求,使用accept函数接受连接,并使用send和recv函数发送和接收数据等。
三、TCP编程在网络编程中,常用的通信协议之一是TCP(Transmission Control Protocol,传输控制协议)。
了解CCMoveToCCCallFuncNCCSequence用法
![了解CCMoveToCCCallFuncNCCSequence用法](https://img.taocdn.com/s3/m/7ef69838443610661ed9ad51f01dc281e53a56bb.png)
了解CCMoveTo CCCallFuncN CCSequence用法在《iPhone &iPad Cocos2D游戏开发实战》一书中在看第四章时候遇到陌生知识,然后在网上找到相关知识点,再此记录;由序列控制蜘蛛的移动方法代码[cpp]view plaincopy1.-(void) runSpiderMoveSequence:(CCSprite*)spider {2.// 随着时间慢慢增加蜘蛛的移动速度3.numSpidersMoved++;//定义的int型变量4.if (numSpidersMoved % 8 == 0 && spiderMoveDuration > 2.0f) {5.spiderMoveDuration -= 0.1f; }6.// 用于控制蜘蛛移动的动作序列7.CGPoint belowScreenPosition = CGPointMake(spider.position.x,8.-[spider texture].contentSize.height);MoveTo* move = [CCMoveTo actionWithDuration:spiderMoveDuration position:belowScreenPosition];CallFuncN* call = [CCCallFuncN actionWithTarget:self selector:@selector(spiderBelowScreen:)];Sequence* sequence = [CCSequence actions:move, call, nil];12.[spider runAction:sequence];13.}RunSpiderMoveSequence方法的作用是跟踪已被放下的蜘蛛数量。
每次到第八个蜘蛛时,spiderMoveDuration的值就会被减少,从而提高所有蜘蛛的移动速度。
蜘蛛纸牌c语言课程设计
![蜘蛛纸牌c语言课程设计](https://img.taocdn.com/s3/m/9c38423b0a1c59eef8c75fbfc77da26925c5963f.png)
蜘蛛纸牌c语言课程设计一、课程目标知识目标:1. 让学生掌握C语言的基本语法和结构,特别是数组、循环和条件语句的使用。
2. 借助蜘蛛纸牌游戏案例,让学生理解并应用面向过程的编程思想,培养问题分析及解决能力。
3. 让学生掌握利用C语言进行简单的数据结构和算法设计。
技能目标:1. 培养学生运用C语言编写程序的能力,特别是针对蜘蛛纸牌这类逻辑性较强的游戏。
2. 通过课程实践,提高学生调试和优化程序的能力,确保程序的稳定性和高效性。
3. 培养学生在团队协作中有效沟通和共同解决问题的能力。
情感态度价值观目标:1. 激发学生对计算机编程的兴趣,培养其主动探究和创新的意识。
2. 培养学生面对困难时的耐心和毅力,增强克服问题的信心。
3. 引导学生认识到编程在生活中的应用价值,树立正确的科技观念。
课程性质分析:本课程为C语言程序设计实践课程,通过蜘蛛纸牌游戏案例,将理论知识与实际应用紧密结合,提高学生的编程技能。
学生特点分析:学生处于具备一定编程基础知识的年级,对新鲜事物充满好奇心,但个体差异较大,需要针对不同层次的学生设计不同难度的教学活动。
教学要求:1. 注重理论与实践相结合,强调动手实践能力。
2. 以学生为主体,关注个体差异,实施差异化教学。
3. 创设真实问题情境,引导学生主动探究,培养解决问题的能力。
二、教学内容1. C语言基础知识复习:数组、循环、条件语句、函数。
2. 蜘蛛纸牌游戏规则介绍及逻辑分析。
3. C语言实现蜘蛛纸牌游戏的步骤分解:a. 游戏界面设计及数据结构定义。
b. 游戏初始化及牌堆、牌桌管理。
c. 玩家操作及游戏逻辑处理。
d. 游戏结束条件判断及胜负判定。
4. 程序调试与优化技巧。
5. 团队协作与项目管理。
教学内容安排和进度:第1周:C语言基础知识复习,介绍蜘蛛纸牌游戏规则。
第2-3周:分析蜘蛛纸牌游戏逻辑,讲解游戏实现步骤。
第4周:分组讨论,制定编程计划,分工合作。
第5-6周:编写程序,实现蜘蛛纸牌游戏。
昆虫繁殖c语言
![昆虫繁殖c语言](https://img.taocdn.com/s3/m/88fadfa2a1116c175f0e7cd184254b35eefd1a1e.png)
昆虫繁殖c语言如何用C语言模拟昆虫的繁殖过程?昆虫繁殖是生物学中一个重要的研究领域,它涉及到复杂的生物过程和生态环境。
为了研究昆虫繁殖的规律和特性,可以通过利用计算机模拟的方法,来模拟昆虫的繁殖过程。
下面,我将会介绍如何用C语言来实现昆虫繁殖的模拟过程。
第一步:定义昆虫的基本属性我们需要定义昆虫的基本属性,例如体重、寿命、繁殖周期等。
这些基本属性将决定昆虫的生长、繁殖和寿命等基本特征。
在C语言中,可以通过结构体来定义昆虫的属性,例如:```struct Insect {float weight;int life_span;int reproductive_period;};```这里,weight表示昆虫的体重,life_span表示昆虫的寿命,reproductive_period表示昆虫的繁殖周期。
我们可以通过初始化这些属性来创建一个新的昆虫对象,例如:```struct Insect insect = {0.2, 30, 7}; //创建一个体重为0.2,寿命为30,繁殖周期为7的昆虫对象```第二步:模拟昆虫的繁殖过程在模拟昆虫的繁殖过程中,我们需要考虑昆虫的繁殖率、繁殖数量以及新生昆虫的生长和寿命等因素。
下面是一个简单的繁殖模拟函数:```void breed(struct Insect *insect, int days) {int num_breed = days / insect->reproductive_period;float rate_breed = num_breed * 0.8; //繁殖率为繁殖周期的0.8倍int num_newborn = num_breed * rate_breed;insect->weight += num_newborn * 0.01; //新生昆虫体重为0.01insect->life_span -= days;}```这里,breed函数接受一个Insect指针和一个表示天数的整数变量。
易语言写请求头和协议头
![易语言写请求头和协议头](https://img.taocdn.com/s3/m/331736554531b90d6c85ec3a87c24028915f8503.png)
易语言写请求头和协议头
摘要:
1.幽灵蛛的简介
2.幽灵蛛的特点
3.幽灵蛛的生活习性
4.幽灵蛛的传说和文化意义
5.幽灵蛛的趣味之处
正文:
1.幽灵蛛的简介
幽灵蛛,学名为“跳蛛”,属于蛛形纲、跳蛛科,是一种分布广泛的小型蜘蛛。
在我国,它们的身影遍布各地,从寒冷的高原到炎热的沙漠,都能见到它们的存在。
尽管它们极为常见,但人们对这种神秘的小生物却知之甚少。
2.幽灵蛛的特点
幽灵蛛体型娇小,通常只有几毫米大小,但它们的跳跃能力却相当出色。
它们的后腿非常强壮,可以使它们迅速地跳跃到目标位置。
这使得它们成为蛛类中的“跳跃高手”。
3.幽灵蛛的生活习性
幽灵蛛是典型的捕食性蜘蛛,它们以各种昆虫为食。
有趣的是,它们捕食的方式与其他蜘蛛截然不同。
它们不会用蛛丝缠绕猎物,而是通过强大的跳跃能力迅速捕捉到猎物,并用毒液将其麻醉。
4.幽灵蛛的传说和文化意义
在古代传说中,幽灵蛛被认为是吉祥之物,可以带来好运和财富。
在一些民间信仰中,人们甚至会在家中摆放幽灵蛛的图案或者饰品,以求好运。
同时,幽灵蛛在文学作品中也多有出现,如《西游记》中的“蜘蛛精”等。
5.幽灵蛛的趣味之处
尽管幽灵蛛看似微不足道,但它们的世界却充满了趣味。
例如,它们在求偶时会用特殊的舞蹈吸引异性,这种舞蹈被称为“蛛舞”。
另外,幽灵蛛的变色
能力也是一大亮点,它们可以根据周围环境改变体色,以达到保护自己的目的。
总的来说,幽灵蛛是一种充满趣味的生物。
它们的独特之处不仅体现在生活习性上,还在于与人类文化的紧密联系。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C 语言编写一个网络蜘蛛可能大家经常要去互联网上搜索特定的内容,比如收集大量邮件地址,如果用google 之类的搜索引擎是没法实现这种特定功能的,所以用 C 语言来写一个吧。
它的功能就是不断去取得网络上的页面,然后分析出网页上出现的邮件地址保存下来。
象个蜘蛛一样,从网络上一个网页爬向另一个网页,不停止地搜索邮件地址。
当然这只是一个原理展示程序,并没有进行优化。
这个程序的main 函数流程图如下:即:分析程序运行时的参数,把各网页地址作为根节点加入到链表,然后从链表头开始处理各节点对整个链表的处理是先处理兄弟节点,流程图如下:然后再处理各节点的子节点,流程图如下:当然,这里采用了递归调用方法,处理子节点的数据时和处理整个链表一样循环处理就是了。
/************关于本文档******************************************** *filename: 用C 语言编写一个网络蜘蛛来搜索网上出现的电子邮件地址*purpose: 一个邮址搜索程序的雏形*wrote by: zhoulifa(zhoulifa@) 周立发()Linux爱好者Linux知识传播者SOHO族开发者最擅长C语言*date time:2006-08-31 21:00:00*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途* 但请遵循GPL*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力***************************************************************** ****/程序在运行的过程中要建立一个树形链表结构,结构图如下:程序启动时分析所带参数,把各参数加入到根网页节点,如果有多个参数则这个根网页有兄弟节点。
然后从根节点开始处理这一级上各节点,把各节点网页上出现的网页链接加到该节点的子节点上,处理完当前这一级后处理子节点这一级。
源代码如下:[code]#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 1typedef 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, * NodeT ail, * NodeCurr;char * mapped_mem;int GetHost(char * , char ** , char ** , int * , char ** ); /**/void AnalyzePage(WEBNODE *); /**/void AddInitNode(char *, char *, int, char * ); /**/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,"\tSocket Error:%s\a\n",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, "\tConnect Error:%s\a\n", 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, "\tsend error!%s\n", strerror(errno));exit(0);} totalsend+=dsend;fprintf(stdout, "\n\tRequest.%d %d bytes send OK!\n", 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);_sec = 10;_usec = 0;if(sockfd > 0) FD_SET(sockfd, &writefds);else {fprintf(stderr, "\n\tError, socket is negative!\n"); exit(0);}ret = select(sockfd + 1, &writefds, NULL, NULL, &tival);if(ret ==0 ) {if(retry++ < 10) goto __ReCeive;}if(ret <= 0) {fprintf(stderr, "\n\tError while receiving!\n"); 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, "create file '%s' error\n", NodeCurr->file); return;}/* receive data from web server */while((nbytes=read(sockfd,buffer,1))==1){if(i < 4) { /* 获取HTTP 消息头*/if(buffer[0] == '\r' || buffer[0] == '\n') 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, "\tRequest.%d is:\n%s", ++reqn, request);DoOnce();if(flag) fprintf(stdout, "\n\tThe following is the response header:\n%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@) 周立发()Linux爱好者Linux知识传播者SOHO族开发者最擅长C语言*date time:2006-08-31 21:00:00*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途* 但请遵循GPL*Thanks to: 广东省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:\n\t%s WebPageAddress1 WebPageAddress2 WebPageAddress3 ...", argv[0]); exit(0);}NodeHeader = NodeT ail = 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'\n", argv); exit(0);}AddInitNode(WebHost, PageAddress, WebPort, WebDir); /* add this page to chain */}free(WebHost); free(PageAddress);free(WebDir);if(DEBUG) {fprintf(stdout, "\nDisplay.%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, 0, sizeof(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, "\nDisplay.%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, "\n");while(TempNode) {if(!strcmp(TempNode->dir, "/")) 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);else 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);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,"\tGethostname '%s' error, %s\n", 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/%sHTTP/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);else 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);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, 0, 1024);memcpy(myemail, pc, strlen(pc) - strlen(pd));if(strcmp(NodeCurr->dir, "/")) fprintf(mailfp, "%s\thttp://%s/%s/%s\n", myemail, NodeCurr->host, NodeCurr->dir, strcmp(NodeCurr->page, "@")?NodeCurr->page:"");else fprintf(mailfp, "%s\thttp://%s%s%s\n", 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 {*d = 0; return ;}while(x) {if(*x >= 'a' && *x <= 'z') {x--; continue;}else if(*x >= 'A' && *x <= 'Z') {x--; continue;}else if(*x >= '0' && *x <= '9') {x--; continue;}else if(*x == '.' || *x == '-' || *x == '_') {x--; continue;}else {break;}}x++;if(x) *d = x;else *d = 0;}/************************************************************** 功能:从src 中找出后面的字母、数字等内含,即email 地址中@ 的后面部分***************************************************************/ void GetAfterPos(char * src, char ** d){char * x;if(src + 1) x = src + 1;else {*d = 0; return ;}while(x) {if(*x >= 'a' && *x <= 'z') {x++; continue;}else if(*x >= 'A' && *x <= 'Z') {x++; continue;}else if(*x >= '0' && *x <= '9') {x++; continue;}else if(*x == '.' || *x == '-' || *x == '_') {x++; continue;}else {break;}}if(x) *d = x;else *d = 0;}/************************************************************** 功能:从src 中找出前面的字母、数字等内含,即一个网页地址中主机名后面的部分***************************************************************/ void GetAfterPosWithSlash(char * src, char ** d){char * x;if(src) x = src;else {*d = 0; return ;}while(x) {if(*x >= 'a' && *x <= 'z') {x++; continue;}else if(*x >= 'A' && *x <= 'Z') {x++; continue;}else if(*x >= '0' && *x <= '9') {x++; continue;}else if(*x == '.' || *x == '-' || *x == '_' || *x == '=') {x++; continue;}else if(*x == ':' || *x == '/' || *x == '?' || *x == '&') {x++; continue;}else {break;}}if(x) *d = x;else *d = 0;}/**************************************************************功能:为myanchor 分配len 大小的内存***************************************************************/ void GetMemory(char ** myanchor, int len){if(!(*myanchor)) (*myanchor) = (char *)malloc(len + 1);else (*myanchor) = (char *)realloc((void *)(*myanchor), len + 1);memset((*myanchor), 0, len + 1);}/**************************************************************功能:从src 中分析出网页链接,并加入到当前节点的子节点上***************************************************************/ void GetLink(char * src){char * pa, * pb, * pc;char * myanchor = 0;int len = 0;pa = src;do {if((pb = strstr(pa, "href='"))) {pc = strchr(pb + 6, '\'');len = strlen(pb + 6) - strlen(pc);GetMemory(&myanchor, len);memcpy(myanchor, pb + 6, len);}else if((pb = strstr(pa, "href=\""))) {pc = strchr(pb + 6, '"');len = strlen(pb + 6) - strlen(pc);GetMemory(&myanchor, len);memcpy(myanchor, pb + 6, len);}else if((pb = strstr(pa, "href="))) {GetAfterPosWithSlash(pb + 5, &pc);len = strlen(pb + 5) - strlen(pc);GetMemory(&myanchor, len);memcpy(myanchor, pb + 5, len);}else {goto __returnLink ;}/*if(DEBUG) {if(strcmp(NodeCurr->dir, "/")) fprintf(stdout, "%s\thttp://%s/%s/%s\n", myanchor, NodeCurr->host, NodeCurr->dir, strcmp(NodeCurr->page, "`")?NodeCurr->page:"");else fprintf(stdout, "%s\thttp://%s%s%s\n", myanchor, NodeCurr->host, NodeCurr->dir, strcmp(NodeCurr->page, "`")?NodeCurr->page:"");}*/if(strlen(myanchor) > 0) AddChildNode(NodeCurr, myanchor);if(pc + 1) pa = pc + 1;}while(pa);__returnLink:return;}/**************************************************************功能:为当前节点增加子节点***************************************************************/ void AddChildNode(WEBNODE * node, char * src){int WebPort, len;char * WebHost = 0, * PageAddress = 0, * WebDir = 0, * pC = 0;WEBNODE * NewNode;char filename[MAXFILENAME + 1] = "";char IsFromRoot = 0;if(!src) return;if(!strncasecmp(src, "mailto:", strlen("mailto:"))) return ;if(strstr(src, ".css")) return;if(strstr(src, ".xml")) return;if(strstr(src, ".ico")) return;if(strstr(src, ".jpg")) return;if(strstr(src, ".gif")) return;if(strstr(src, "javascript:")) return;if(strstr(src, "+")) return;ret = GetHost(src, &WebHost, &PageAddress, &WebPort, &WebDir);if(ret) {len = strlen(node->host);GetMemory(&WebHost, len);strcpy(WebHost, node->host);WebPort = node->port;IsFromRoot = !strncmp(src, "/", 1);if(IsFromRoot && (src + 1)) Rstrchr(src + 1, '/', &pC);else if(!IsFromRoot) Rstrchr(src, '/', &pC);else pC = 0;if(pC) {if(IsFromRoot) len = strlen(src + 1) - strlen(pC);else len = strlen(src) - strlen(pC) + strlen(node->dir) + 1;GetMemory(&WebDir, len);if(IsFromRoot) memcpy(WebDir, src + 1, len);else {memcpy(WebDir, node->dir, strlen(node->dir)); strcat(WebDir, "/"); memcpy(WebDir + strlen(node->dir) + 1, src, strlen(src) - strlen(pC));}if(pC + 1) {len = strlen(pC + 1);GetMemory(&PageAddress, len);strcpy(PageAddress, pC + 1);}else {len = 1;GetMemory(&PageAddress, len);memcpy(PageAddress, e, len);}}else {if(IsFromRoot) {len = 1;GetMemory(&WebDir, len);memcpy(WebDir, e + 1, len);len = strlen(src + 1);GetMemory(&PageAddress, len);memcpy(PageAddress, src + 1, len);}else {len = strlen(node->dir);GetMemory(&WebDir, len);memcpy(WebDir, node->dir, len);len = strlen(src);GetMemory(&PageAddress, len);memcpy(PageAddress, src, len);}}}ret = IsExistWeb(NodeHeader, WebHost, PageAddress, WebPort, WebDir);if(ret) goto __ReturnAdd;if(node->child == NULL) NewNode = node->child = (WEBNODE *)malloc(sizeof(WEBNODE));else NodeTail->brother = NewNode = (WEBNODE *)malloc(sizeof(WEBNODE));memset(NewNode, 0, sizeof(WEBNODE));NewNode->host = (char *)malloc(strlen(WebHost) + 1);memset(NewNode->host, 0, strlen(WebHost) + 1);NewNode->page = (char *)malloc(strlen(PageAddress) + 1);memset(NewNode->page, 0, strlen(PageAddress) + 1);NewNode->dir = (char *)malloc(strlen(WebDir) + 1);memset(NewNode->dir, 0, strlen(WebDir) + 1);NewNode->file = (char *)malloc(MAXFILENAME + 1);memset(NewNode->file, 0, MAXFILENAME + 1);strcpy(NewNode->host, WebHost);strcpy(NewNode->page, PageAddress);strcpy(NewNode->dir, WebDir);sprintf(filename, "file%05d.html", FileNumber++);strcpy(NewNode->file, filename);NewNode->port = WebPort;NewNode->IsHandled = 0;NewNode->brother = 0;NewNode->child = 0;NodeTail = NewNode;__ReturnAdd:free(WebHost); free(PageAddress); free(WebDir);}/**************************************************************功能:检查是否已经处理过的网页***************************************************************/ int IsExistWeb(WEBNODE * node, char * host, char * page, int port, char * dir) {WEBNODE * t;t = node;while(t) {if(!strcmp(t->host, host) && !strcmp(t->page, page) && t->port == port && !strcmp(t->dir, dir)) return 1;t = t->brother;}t = node;while(t) {if(t->child) {ret = IsExistWeb(t->child, host, page, port, dir);if(ret) return 2;}t = t->brother;}return 0;}[/code]编译这个程序:QUOTE:gcc mailaddrsearch.c -o mailsearcher输入一个网址作为参数运行一下试试吧:QUOTE:./mailsearcher /5531748.html程序首先找出/5531748.html 页面上的邮件地址保存到当前目录下email.txt 文件里,每行一条记录,格式为邮件地址和出现该邮件地址的网页。