以一种"廉价"的方式获取页面的标题(downmoon)

系统 1718 0

有朋友问到:
“我需要得到一个web page的title,因为这个title一般都比较靠前,只要取得html 的前面少量内容就可以了。因为要取得很多个页面的title,如果下载整个html code, 肯定比较浪费时间。.net好像没有现成的类可以干这件事情(取得部分html) ,我应该如何去实现?”
一种比较"廉价"(即较小成本条件下)的解决思路:
第一步:取出含有页面title部分的最小集合。这是“廉价”的关键!
第二步:用正则表达式取出<title>和</title>之间的部分即可。
先看下效果:


下面我们来分析:
页面title 一般都在靠近开始处,所以我们从开始读取Stream流,(如果靠近结尾,则如何?)读取到什么地方为止呢?有个比较明显的标志是
</title>
遇到它结束就可以了。
以什么方式读取,我这里选取的是:逐行读取,取到标志符即终止。
方法如下:


<!-- {cps..2}--> #region 获取所需要的页面内容
/// <summary>
/// 获取所需要的页面内容bytony2009.9,16
/// 邀月(downmoon):3w@live.cn
/// <paramname="strUrl"> 所要查找的远程网页地址 </param>
/// <paramname="timeout"> 超时时长设置,一般设置为8000 </param>
/// <paramname="enterType"> 是否输出换行符,0不输出,1输出文本框换行 </param>
/// <paramname="EnCodeType"> 编码方式 </param>
/// <returns></returns>
public static string GetRequestString( string strUrl, int timeout, int enterType,EncodingEnCodeType)
{

if (strUrl.Equals( " about:blank " )) return null ;;
if ( ! strUrl.StartsWith( " http:// " ) && ! strUrl.StartsWith( " https:// " )){strUrl = " http:// " + strUrl;}
string strResult = string .Empty;
System.IO.StreamReadersr
= null ;
string temp = string .Empty;
try
{
HttpWebRequestmyReq
= (HttpWebRequest)HttpWebRequest.Create(strUrl);
myReq.Timeout
= timeout;
myReq.UserAgent
= " User-Agent:Mozilla/5.0(compatible;MSIE6.0;WindowsNT5.2;SV1;.NETCLR2.0.40607;.NETCLR1.1.4322;.NETCLR3.5.30729) " ;
myReq.Accept
= " */* " ;
myReq.KeepAlive
= true ;
myReq.Headers.Add(
" Accept-Language " , " zh-cn,en-us;q=0.5 " );
HttpWebResponseHttpWResp
= (HttpWebResponse)myReq.GetResponse();
if (HttpWResp.StatusCode == System.Net.HttpStatusCode.OK)
{
StringBuilderstrBuilder
= new StringBuilder();
StreammyStream
= HttpWResp.GetResponseStream();
sr
= new StreamReader(myStream,EnCodeType);
string tmp = string .Empty;
while ((temp = sr.ReadLine()) != null )
{
strBuilder.Append(temp);
// ifhas</title>thenendbydownmoon(邀月)2009.9.16
tmp = strBuilder.ToString();
if (tmp.IndexOf( " </title> " ) > 0 ){ break ;}
if (enterType == 1 ){strBuilder.Append( " /r/n " );}
}
strResult
= strBuilder.ToString();
return strResult;
}
return string .Empty;
}
catch (Exceptionex)
{
// #regionLoghandlebyTony2008.11.21
return strResult;
// #endregion
}
finally { if (sr != null ){sr.Close();}}
}
#endregion

取出后就是再用正则取出<title>和</title>之间的部分。
这部分浪费了些时间,因为邀月的正则功底不行啊!·
先后试过如下正则表达式:

<!-- {cps..5}--> 1 // stringstrRegEx="<[^>]*>";
2 // stringstrRegEx="<title>.*([^</title>])";
3 // stringstrRegEx="<title>(.*?)</title>";
4 // stringstrRegEx="<title>.*?</title>";

均不能达到想要的“经济廉价”的效果,最终,找到这个:



<!-- {cps..8}--> public static string GetContextByHtml( string sHtml)
{
// stringregex="(<title[>])(.*)(<//title>)";
string regex = @" (?<=<title.*>)([/s/S]*)(?=</title>) " ;
System.Text.RegularExpressions.Regexex
= new System.Text.RegularExpressions.Regex(regex,System.Text.RegularExpressions.RegexOptions.IgnoreCase);
return ex.Match(sHtml).Value.Trim();
}


演示效果如上图:

后续问题:
1、将继续实现代理方式躲过IP;
2、将尝试另外一种通过Request.Filter方式直接替换来实现。
欢迎交流。
助人等于自助! 3w@live.cn

以一种"廉价"的方式获取页面的标题(downmoon)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论