关于C#远程获取网页内容的程序及源代码在网上到处都可以找到,说到底也就是某一位“高手”写出来放在网上,其余的人都COPY来的。其实这个源代码在Studio2003或Studio2005的帮助文档中有现成的,只是我们没发现而已。
网上的源代码绝大部分是这样的:
using System;
using System.Net;
using System.IO;
using System.Collections;
using System.Text;
namespace webthief
{ class Class1
{[STAThread]
static void Main(string[] args)
{ try{
WebClient MyWebClient = new WebClient();
MyWebClient.Credentials = CredentialCache.DefaultCredentials;//获取或设置用于对向Internet资源的请求进行身份验证的网络凭据。
Byte[] pageData = MyWebClient.DownloadData("http://www.baidu.com");//从指定网站下载数据
string pageHtml = Encoding.Default.GetString(pageData); //如果获取网站页面采用的是GB2312,则使用这句
//string pageHtml = Encoding.UTF8.GetString(pageData); //如果获取网站页面采用的是UTF-8,则使用这句
Console.WriteLine(pageHtml);//在控制台输入获取的内容
using (StreamWriter sw = new StreamWriter("e://ouput.html"))//将获取的内容写入文本
{
sw.Write(pageHtml);
}
Console.ReadLine(); //让控制台暂停,否则一闪而过了
}
catch(WebException webEx){
Console.WriteLine(webEx.Message.ToString());
}
}
}
}
这个程序确实能够抓住网页中的内容,但可惜的是有些网页内容写入文件后e://ouput.html再打开,你却发现网页内容上的汉字是一片乱码,当然这其中的原因有可能是网页的编码方式不一样,一开始我也以为是这样。但遗憾是换了几种编码方式都是一样。后来无意中发现有一种方法可以解决该问题,我把它贴在这里,与大家一起探讨。
解决乱码的方法:先把网页内容写入txt文件,然后再手工将该文件另存为html文件,这样打开的文件就跟真网页内容一模一样了。至于这里面的原因,我也没搞清楚。
上面的方法所获得的实际上是在浏览器中所能显示的所有html代码。这种方法对一部分网页显然是很有用的,但是当网页中含有框架、页面嵌套或用.js文件嵌入时,在源文件中看到的只是很少的html代码,主体部分根本无法看到,这时用上面的方法自然也无法得到网页中的内容了。有人可能想到用IE缓存,网页在显示前一般都在下载到本地IE缓存,如果能把里面的内容读出来就OK了。但本人比较笨,没有找到一个行之有效的办法来解决IE缓存数据读取问题。后来上网搜了一下关于获取网页内容的方法,发现有人在C#中用microsoft web浏览器控件能够获取网页。赶紧搜一下MSDN,找该控件的使用方法,竟然没有,估计是没装完全。再到网上搜,发现有VB.net中该控件的用法,这时记起一位博士师兄曾做过类似的程序,问题很相似,马上查一下师兄的程序,果然用的就是浏览器控件,不过他用的也是VB。
既然有了代码,就不怕语言的问题,微软各开发语言之间相差不大,C#中用法跟VB中用法很相似。下面贴出几行关键代码:
先添加microsoft web浏览器控件,该控件必须另外添加,不在工具箱(工具箱的microsoft web浏览器没有该功能)。
其次在某一个事件比如按钮的click事件(随你喜欢)中添加下面的几行代码(注意不是所有代码,其它的一些代码自己加),axWebBrowser为浏览器控件名。
axWebBrowser.Navigate("http://www.baidu.com",ref blank,ref blank,ref blank,ref blank);
//Navigate打开网页,第一个参数是网址,后面的blank是一个object对象。
Clipboard.SetDataObject(""); //清空剪贴板
axWebBrowser.ExecWB(SHDocVw.OLECMDID.OLECMDID_SELECTALL,SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT,ref blank,ref blank);
//将网页上的内容全选
axWebBrowser.ExecWB(SHDocVw.OLECMDID.OLECMDID_COPY,SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT,ref blank,ref blank);
//将选中的内容复制
axWebBrowser.ExecWB(SHDocVw.OLECMDID.OLECMDID_PASTE,SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT,ref blank,ref blank);
//将复制的内容粘贴到剪贴板(默认)
String pageHtml = (string) (Clipboard.GetDataObject().GetData (DataFormats.Text ));
//取出剪贴板中的内容放入pageHtml变量
上面的方法有一个缺点,它得到的是网页显示的所有文字,但图片等其它非文字的内容无法获取下来。并且在执行全选操作之前,要确保网页已全部显示完毕。要命的是,它可能对某些网站不适用,如对百度就无法获取任何内容,原因不明。