[导入]网络蜘蛛研究之总体设计及信息获取
编写一个这样的蜘蛛程序,一般的顺序是:
2. 分析获取的网页内容, 进行信息分类,并且分析出url, 进行下一次获取网页.
3. 将归类之后的信息保存进数据库.
难点: 分析出url, 应用多线程提高程序效率.
根据以上几点,我特将此问题分解成若干个子问题,一一突破. 如果用递归的形式来思考这个问题,则只要考虑如何分析单一页面,并且假定待访问url栈为其他线程共享资源. 这里为什么用栈而不用队列? 原因就是先进栈的url应该是与正在处理的url联系最紧密的, 这样有利于相同信息的比较!
while(待访问的url栈为空?){
出栈.
激活线程.
}
线程(){
根据url抓取内容;
获取信息:保存信息
获取url:将url置入待访问栈.
}
由上面可以看出,解决了单一线程访问某个单一页面这个难题, 则整个蜘蛛程序核心的部分也就完成. 在这里我将采用C# 来开发这个蜘蛛程序,原因有3, C#是我比较熟悉的一种编程语言,而且.net环境比较熟悉. 二. .net 内置了http访问功能,这样url获取网页内容就非常好解决. 三 C#本身就支持多线程,开发多线程的程序将变得非常简单! 所以基于以上几点考虑, 采用C#来做这个蜘蛛是最合适不过的了. 在我的博客上转载了几篇关于蜘蛛以及获取网页信息的文章, 个人感觉非常不错. 我也主要是研究那几篇帖子来完成此程序的. 当然能不能达到预期的效果, 就看未来几天的努力了!
今天将抓取信息的部分,封装进了我的luotongUnit类库, 类的名字为 NetSpider ,这个类我将设计成具有以下几个功能:
1. 通过url获取网页内容,并返回string.
2.连接分析. 通过传入的 字符串xx 分析出内容(xx),以及连接(link) 并返回. 此处打算设置成一个 连接的 struct.
3. 根据抓取的内容,返回去掉标签及首尾标记符的 内容.
4. 其他功能暂定! 毕竟现在还不能知道具体的细分规则!
现在此类以具有根据url获取网页内容的功能, 并且写了简单的demo程序测试.
namespace luotongUnit
{
///
/// 主要用于获取Internet上的信息。
/// 1、根据Url获取文本及2进制内容。
/// 2、Html分析。
/// 3、还有其他的功能暂时没有想到!
/// 2006.1.10
///
///
public class NetSpider
{
public static string Get_Http(string url,int timeout)
{
try
{
HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(url) ;
myReq.Timeout = timeout;
HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
Stream myStream = HttpWResp.GetResponseStream () ;
StreamReader sr = new StreamReader(myStream,Encoding.Default);
StringBuilder strBuilder = new StringBuilder();
while (sr.Peek()!=-1)
{
strBuilder.Append(sr.ReadLine()+"\r\n");
}
return strBuilder.ToString();
}
catch(Exception exp)
{
return "错误:" + exp.Message ;
}
}
}
}
demo程序调用为:
private void btnOk_Click(object sender, System.EventArgs e)
{
string strUrl="";
string strDir="";
if (txtUrl.Text!=Url_Default) strUrl=txtUrl.Text;
if(txtDir.Text!=Dir_Default) strDir=txtDir.Text;
strUrl=strUrl.ToLower();
if(strUrl.IndexOf("http://")==-1) strUrl="http://"+strUrl;
txtResult.Text=NetSpider.Get_Http(strUrl,10000);
}
到现在, 已经完成了此蜘蛛程序的 获取页面功能,这也从根本上解决了获取内容,保存内容2个问题( 因为保存内容到数据库是我的强项). 在接下来的几天里,我将陆续完成html分析的功能,并且将功能细分,最终完善 NetSpider 类.
[转]网络蜘蛛研究之正则表达式
在昨天发表的那篇网络蜘蛛研究中提到了对获取html进行分析这一问题. 开始想用字符判断来完成,后来发现这样编程的工作太过于巨大. 而以前用asp处理ubb码的时候用到过正则表达式, 这对于分析html代码非常有帮助,所以想将html的分析转换为特定的正则表达式. 其实对于html的分析,我们可以引用编译原理里的"遍"这个概念. 你想要一次处理完这么多信息是不可能, 需要一遍一遍的过滤. 而每一遍完成对特定html标签的处理. 于是基本思路定于:
第1遍: 读取特定网站的特征文件! 在开始过程中,我个人认为可以将首页url以及特征文件做为输入项. 这个特征文件应该包含: 从哪个特殊字符开始过滤. 而只留下与内容结合最紧密的html源代码.
第2遍: 过滤掉背景,布局等布局标签.
第3遍: 从省下的代码中过滤出 url, 主题信息. 以及图片url
上面3遍其实是大致的分步, 而每一步又可以有若干个小步骤. 如果从这个思路出发, 那么我的NetSpider类其他的功能就应该是对 常用html进行过滤的静态函数. 这些函数主要供第2遍及第3遍使用. 而第一遍应该根据过滤文件来来写相应的程序. 对于这种复杂的过滤, 正则表达式是最好的方法! 在我的blog中,我转载了2篇关于正则表达式的文章,相信大家看了这2篇文章后应该对正则的强大功能有个大概的了解.
下面我介绍下C#里使用正则需要用到的类. 首先C#的正则表达式需要调用System.Text.RegularExpressions 命名空间.
下面我以一个简单的例子说明如何使用正则. 此例子是昨天那个抓取函数的正则改良版.
private void btnOk_Click(object sender, System.EventArgs e)
{
string strUrl="";
string strDir="";
if (txtUrl.Text!=Url_Default) strUrl=txtUrl.Text;
if(txtDir.Text!=Dir_Default) strDir=txtDir.Text;
Regex reg=new Regex("^http://",RegexOptions.IgnoreCase|RegexOptions.Compiled);
Match mResult=reg.Match(strUrl);
if(!mResult.Success) strUrl="http://"+strUrl;
txtResult.Text=NetSpider.Get_Http(strUrl,10000);
}
可以对比下昨天的代码。 其中判断输入的连接是否以 http:// 开头这里改成了用正则表达式来判断。而其中的RegexOptions.IgnoreCase|RegexOptions.Compiled 代表忽略大小写并且编译改正则表达式。
至此对于正则表达式的初步探索也就告一段落了,其实更深入的正则表达式应用可以看.net framework 的帮助文档。 其中有一段对于网络很实用的正则代码:
void DumpHrefs(String inputString)
{
Regex r;
Match m;
r = new Regex("href\\s*=\\s*(?:\"(?<1>[^\"]*)\"|(?<1>\\S+))",
RegexOptions.IgnoreCase|RegexOptions.Compiled);
for (m = r.Match(inputString); m.Success; m = m.NextMatch())
{
Console.WriteLine("Found href " + m.Groups[1] + " at "
+ m.Groups[1].Index);
}
}
以上这个代码可以很方便的进行 超连接提取。
文章来源:http://www.codeguru.cn/ShowThread.aspx?PostID=1309
浙公网安备 33010602011771号