简易网络爬虫程序的开发Word文档格式.docx
- 文档编号:21121738
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:22
- 大小:123.61KB
简易网络爬虫程序的开发Word文档格式.docx
《简易网络爬虫程序的开发Word文档格式.docx》由会员分享,可在线阅读,更多相关《简易网络爬虫程序的开发Word文档格式.docx(22页珍藏版)》请在冰豆网上搜索。
charset=gb2312"
>
title>
XX一下,你就知道
在标签<
meta>
中会指定该页面的编码:
charset=gb2312,所以我的程序中要先读取charset的值,然后再重新按charset的值对读流进行读取,为了使这个过程更加简单,我先统一按"
gb2312"
进行编码,从流中读取html,在分析html的charset值,如果该值也是"
就直接返回html,如果是其它编码就重新读取流。
3.对于有些页面的html可能会非常大所以我们要限制大小,在程序中最在读取不会超过100k
该类完整代码如下:
///<
summary>
///HTTP服务类
///<
/summary>
internalclassHttpServer
{
///获取指定页面html文本
paramname="
url"
页面url<
/param>
publicstringGetResponse(stringurl)
try
stringhtml=string.Empty;
stringencoding=string.Empty;
HttpWebRequestrequest=(HttpWebRequest)WebRequest.Create(url);
request.Method="
get"
;
request.ContentType="
text/html"
byte[]buffer=newbyte[1024];
using(HttpWebResponseresponse=(HttpWebResponse)request.GetResponse())
using(Streamreader=response.GetResponseStream())
using(MemoryStreammemory=newMemoryStream())
intindex=1;
intsum=0;
//限制的读取的大小不超过100k
while(index>
0&
&
sum<
100*1024)
index=reader.Read(buffer,0,1024);
if(index>
0)
memory.Write(buffer,0,index);
sum+=index;
}
html=Encoding.GetEncoding("
).GetString(memory.ToArray());
if(string.IsNullOrEmpty(html))
returnhtml;
else
//解析charset的值
Regexre=newRegex(@"
charset=(?
charset>
[\s\S]*?
)"
"
);
Matchm=re.Match(html.ToLower());
encoding=m.Groups["
charset"
].ToString();
if(string.IsNullOrEmpty(encoding)||string.Equals(encoding.ToLower(),"
))
//不是gb2312编码则按charset值的编码进行读取
returnEncoding.GetEncoding(encoding).GetString(memory.ToArray());
}
catch
return"
}
由于在程序外该类是不可见的,所以声明时用了internal.
AbsChain类
对于AbsChain采用的是职责链设计模式,目的是抽象出网络爬虫处理html的过程,因为在spider程序集中并不真正处理如何解析html,用户只需重载AbsChain类中的process方法,完成自定义的处理过程
程序源码如下:
namespaceWebSpider
{
///职责链抽象类
publicabstractclassAbsChain
privateAbsChain_handler=null;
privatestring_url=string.Empty;
publicstringUrl{get{return_url;
}set{_url=value;
}}
internalAbsChainHandler
get
return_handler;
///文本处理过程
htmlStream"
html文本<
protectedabstractvoidProcess(stringhtml);
///设置下一个处理节点
handler"
下一个处理节点<
publicvoidSetProcessHandler(AbsChainhandler)
_handler=handler;
///开始处理
html文本流<
publicvoidStart(stringhtml)
Process(html);
//处理用户重载方法
if(Handler!
=null)
Handler.Url=Url;
Handler.Start(html);
ChainMain类:
ChainMain类是对AbsChain类的具体实现,但是它的Process方法是个空方法,所以你可以把它理解成它就是具体处理职责链上的头节点,通过ChainMain类的_handler将处理任务往下传递,用户通过调用ChainMain的SetProcessHandler方法设置下一个处理节点,这个节点必须由用户继承AbsChain并实现抽象方法Process。
ChainMain类的源代码如下:
internalclassChainMain:
AbsChain
protectedoverridevoidProcess(stringhtml)
WorkThread类:
WorkThread类是工作线程类,每个工作线程类都包括一个职责链的头节点ChainMain、一个HttpServer类和一个UrlStack,其中UrlStack类采用了单构件设计模式,所以对于整个应该用程序都是使用一个UrlStack对象。
源代码如下:
///工作线程
internalclassWorkThread
privateChainMain_chainHeader=newChainMain();
privateHttpServer_httpServer=newHttpServer();
privatebool_isRun=false;
///职责链的头节点
publicChainMainChainMain
return_chainHeader;
publicHttpServerHttpServer
return_httpServer;
publicboolIsRun{get{return_isRun;
publicUrlStackUrlStack
returnUrlStack.Instance;
}
///工作线程入口函数
种子url<
publicvoidStart()
_isRun=true;
while(_isRun)
//从地址堆栈中取出url
stringurl=UrlStack.Pop();
if(!
string.IsNullOrEmpty(url))
stringhtml=_httpServer.GetResponse(url);
string.IsNullOrEmpty(html))
ChainMain.Url=url;
ChainMain.Start(html);
///停止工作线程
publicvoidStop()
_isRun=false;
Start方法是工作线程的入口方法,它从UrlStack中取出url,并调用HttpServer的GetResponse方法取出Url对应网页的HTML代码,并将HTML代码传递给职责链的头节点ChainMain,由它的Start方法开始处理。
回忆一下AbsChain的Start()方法,它是先调用自身类的Process方法,然后再调用_handler.Start()方法,就这样把处理过程传递下去。
UrlStack类:
UrlStack类非常的简单,它采用单构件设计模式,并维护了一个数据结构,该数据结构用来存储需要爬虫抓取的Url
源码如下:
publicclassUrlStack
privatestaticUrlStack_urlstack=newUrlStack();
privateQueue<
string>
_stack=newQueue<
();
privatereadonlyint_maxLength=Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["
MaxLength"
]);
privateUrlStack(){}
publicstaticUrlStackInstance
get{return_urlstack;
publicvoidPush(stringurl)
lock(this)
_stack.Contains(url))
if(_stack.Count>
=_maxLength)
_stack.Dequeue();
_stack.Enqueue(url);
publicstringPop()
return_stack.Dequeue();
publicintCount{get{return_stack.Count;
在源码中我用的是一个队列,当然,用户也可以改成其它的数据结构,比如:
Stack<
T>
,用队列就有点像广度优先搜索,用堆栈就有点像深度优先搜索。
AbsThreadManager类:
AbsThreadManager的主要功能是管理开启WorkThread工作线程,与监控线线程的,WorkThread对象与Thread对象一一对应,这两个对象都被封在ObjThread对象里,先看看ObjThread源码:
internalclassObjThread
privateWorkThread_workThread;
privateSystem.Threading.Thread_thread;
internalWorkThreadWorkThread{get{return_workThread;
}set{_workThread=value;
internalSystem.Threading.ThreadThread{get{return_thread;
}set{_thread=value;
ObjThread类是非常的简单的,只有一个Thread对象与一个WorkThread对象.
在AbsThreadManagers中用List<
ObjThread>
来维护一系列的线程对象与WorkThread对象,同时在AbsThreadManagers中增加了一个监控线程,用来查看工作线程的工作线程,若工作线程死去,由监控线程重新启动。
publicabstractclassAbsThreadManager
publicint_maxThread=Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["
MaxCount"
internalList<
list=newList<
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 简易 网络 爬虫 程序 开发
