用下面的代码访问中文网页

        string url = "http://www.sohu.com"
        
//变量定义
        MSXML2.XMLHTTPClass xmlHttp;  //用于发送Http请求的MSXML2.XMLHTTPClass类型的变量

        xmlHttp 
= new MSXML2.XMLHTTPClass();

        
//设置http请求的参数
        xmlHttp.open("GET" , url , false , null , null );          
        xmlHttp.setRequestHeader( 
"Accept-Lauguage" , "zh-cn" );  
        xmlHttp.setRequestHeader(
"Content-Type""text/html;charset=gb2312"); 

        
//发送http请求
        xmlHttp.send( null );          
                                
        
if( xmlHttp.status == 200 )          
        {  
//请求成功 
            return xmlHttp.responseText;  //返回网页的源代码
        }
        
else
        {  
//请求失败
            return null;
        }

  返回的结果是这样的(只贴了一部分网页代码,其他的代码也是一样的,就是汉字全是乱码)

<html> 
<head> 
<title>锟匡靠锟匡靠站 - 锟匡靠锟匡靠锟匡靠 系统锟匡靠锟匡靠- 全锟匡靠锟匡靠锟?
</title> 
<meta content="text/html; charset=gb2312" http-equiv="Content-Type"> 
<meta http-equiv=skycn content=no-cache> 
<LINK href="../download/download.css" rel=stylesheet type=text/css> 
</head> 
<body topmargin="0" leftmargin="0" bgcolor="#FFFFFF"> 
 
<table border=0 width=760 height=20 cellspacing=0 cellpadding=0 bgcolor=#DEDEC7 align=center> 
 
<tr> 
 
<td align=left>&nbsp;<font color=#000000> 
 
<a href="../index.html" style="color: #000000"><b>锟恳?/b></a>  |  
 
<a href="../sort/soft_sort.html" style="color: #000000"> 锟匡靠锟縜>  |  
 
<a href="../new/00.html" style="color: #000000"> 锟匡靠</a>  |   
 
<a href="../top/top_000000_a.html" style="color: #000000"> 锟匡靠</a>  |  
 
<a href="../sort/rjfl01_indate_DESC_1.html" style="color: #000000"> 锟匡靠锟匡靠</a>  |  
 
<a href="../sort/rjfl02_indate_DESC_1.html" style="color: #000000"> 锟匡靠锟匡靠</a>  |  
 
<a href="../sort/rjfl03_indate_DESC_1.html" style="color: #000000"> 锟匡靠锟匡靠锟匡靠锟匡靠</a>  |  
 
<a href="../sort/rjfl04_indate_DESC_1.html" style="color: #000000"> 锟匡靠锟匡靠锟匡靠</a>  |  
 
<a href="../sort/sort0000wz_indate_DESC_1.html" style="color: #000000"> 锟匡靠锟匡靠讯</a>  |  
 
<a href="../sort/sort0000qd_indate_DESC_1.html" style="color: #000000"> 锟匡靠锟匡靠</a>  |  
 
<a href="http://shareware.skycn.com" target="_blank" style="color: red"> <b>锟匡靠锟孔靠锟縝></a>  |  
 
<a href="http://www.regsky.com" target="_blank" style="color: red"> <b>锟匡靠注锟匡靠b></a>  |  
 
</td> 
 
<td align=right> 
 
<SCRIPT language=JavaScript1.2> 
 function bookmarkit()  
 {window.external.addFavorite(
'http://www.skycn.com','锟匡靠锟匡靠站锟匡靠锟匡靠每锟匡靠锟匡靠玫模锟?)  
 }if(document.all) 
 document.write(
'<a href="#" onClick="bookmarkit()" class="h1" style="color: blue">锟匡靠锟壳?/a>')</SCRIPT> 
 
</td></tr></table> 

在网上找了一段vbscript代码:

<%
Function GetNewsContent(URL)
set objHttp=server.createobject("Microsoft.XMLHttp")
'objHttp.open "get","http://news.sina.com.cn/news1000/index.shtml",false
objHttp.open "get",URL,false
objHttp.send()
GetNewsContent
=B2B(objHttp.responsebody)
End Function

Function B2B(body)
dim objStream
set objStream=server.createobject("adodb.stream")
objStream.type
=1
objStream.Mode
=3
objStream.Open
objStream.Write body
objStream.Position
=0
objStream.Type
=2
objStream.Charset
="gb2312"
B2B
=objStream.ReadText
set objStream=nothing
End Function
%>

也不知道转换成.net的代码 ,而且xmlHttp.responseText就是string类型的变量,好像不用再转化了,那么怎么样才能得到正确的中文网页那?




以下是csdn chnking(kent)  的回复:
回复人: bluefloat(飘摇) ( 二级(初级)) 信誉:100 2006-2-17 20:02:22 得分: 5

xmlHttpRequest编码转换一下,decoding=default。。。


回复人: chnking(kent) ( 两星(中级)) 信誉:93 2006-2-19 23:10:12 得分: 0

很奇怪,http://www.sohu.com和http://www.tom.com跟 163.com一样都是gb2312的编码,不应该不一样啊.
另外你在发出请求的时候指定 xmlHttp.setRequestHeader("Content-Type", "text/html;charset=gb2312"); 这个没什么意义,还是要看服务端返回给你的是什么编码的,可以通过读取返回的header中的Content-Type来获取服务端返回来的编码,然后根据这个编码来构造相应的读取器.
另外,你如果要抓网页的话,建议采用HttpWebRequest来获取网页,HttpWebRequest是dotnet内建的类,然后将抓来的网页用Sgml转换为xml友好的格式,就可以使用XmlDocment就行分析处理了.


回复人: time_is_life(今夜太冷) ( 五级(中级)) 信誉:77 2006-2-20 10:25:14 得分: 0


>xmlhttp的版本问题,可能你使用的MSXML.dll的版比较旧,MSXML.dll的98版本在98下比较容易
>出现乱码!XP以上的版好些。请你使用新的版本!最好3.0以上

我试验了一下msxml5.0,结果还是出现乱码.

>xmlHttpRequest编码转换一下,decoding=default。。。

对于下面的代码:

MSXML2.XMLHTTPClass xmlHttp;  //用于发送Http请求的MSXML2.XMLHTTPClass类型的变量
xmlHttp = new MSXML2.XMLHTTPClass();
//设置http请求的参数
xmlHttp.open("GET" , url , false , null , null );         
xmlHttp.setRequestHeader( "Accept-Lauguage" , "zh-cn" ); 
xmlHttp.setRequestHeader("Content-Type", "text/html;charset=gb2312");
//发送http请求
xmlHttp.send( null );         

if( xmlHttp.status == 200 )         
{  //请求成功
Response.Write(xmlHttp.responseText);
}
else
{  //请求失败
Response.Write("请求失败");
}

在哪里设置decoding=default阿

>很奇怪,http://www.sohu.com和http://www.tom.com跟 163.com一样都是gb2312的编码,
>不应该不一样啊.

确实不一样,有的网站返回汉字,有的网站就使乱码或者一大堆问号


>另外你在发出请求的时候指定 xmlHttp.setRequestHeader("Content-Type", "text/html;charset=gb2312");
>这个没什么意义,还是要看服务端返回给你的是什么编码的,可以通过读取返回的header中的
>Content-Type来获取服务端返回来的编码,然后根据这个编码来构造相应的读取器.

我用了
string header = "";
...
header = xmlHttp.getResponseHeader( "Content-Type" );
Response.Write( header );

发现tom, sohu,csdn,sina,163等网站返回的都是text/html.
然后我把请求中的一句改成这样:

xmlHttp.setRequestHeader("Content-Type", "text/html");

然后post网页,结果还是一样,163,csdn返回的是中文,sina,sohu,tom返回的都是乱码

>另外,你如果要抓网页的话,建议采用HttpWebRequest来获取网页,
>HttpWebRequest是dotnet内建的类,

我用了下面的代码:

//变量定义
string respstr;

WebRequest myWebRequest=WebRequest.Create(url);

// Assign the response object of 'WebRequest' to a 'WebResponse' variable.
WebResponse myWebResponse=myWebRequest.GetResponse();
System.IO.Stream stream = myWebResponse.GetResponseStream();
StreamReader sr = new StreamReader(stream);
//以字符串形式读取数据流
respstr = sr.ReadToEnd();
sr.Close();

return respstr;

结果csdn返回的是中文,163,sina,tom,sohu返回的都是乱码


>然后将抓来的网页用Sgml转换为xml友好的格式,就可以使用XmlDocment就行分析处理了.

Sgml也是一种文件格式,怎么样利用sgml转换成友好的格式阿,能否给具体一点的提示
另外我现在得到的是乱码,好像用sgml也不奏效吧

回复人: chnking(kent) ( 两星(中级)) 信誉:93 2006-2-20 10:40:26 得分: 15

>>发现tom, sohu,csdn,sina,163等网站返回的都是text/html.
我看了一下,tom、sina、sohu都是<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
csdn是:<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

>>StreamReader sr = new StreamReader(stream);
这里有问题,StreamReader默认的编码都是UTF-8,如果你不指定编码就是使用默认的UTF-8行解码,所以你看到的结果是csdn的没有乱码(就它使用的是UTF-8编码),别的都乱了。这里要用StreamReader(Stream stream,Encoding encoding)这个构造方法,指定流的编码,这里的encoding就是具体你抓到网页的编码,使用返回网页的Content-Type获知网页使用的编码,时候使用相应的Encoding去构造StreamReader就ok了

>>Sgml也是一种文件格式,怎么样利用sgml转换成友好的格式阿,能否给具体一点的提示
另外我现在得到的是乱码,好像用sgml也不奏效吧
这里我写错了,应该是SgmlReader,一个转换成xml友好格式的开源组件。



结合以上描述,我确定的解决方案如下:

(1)在服务器端使用WebRequest而不是xmlHttp
(2) 将

StreamReader sr = new StreamReader(stream);

对于简体中文改成:

StreamReader sr = new StreamReader(stream , Encoding.Default );

对于utf-8改成:

StreamReader sr = new StreamReader(stream , Encoding.UTF8 );

当然,Encoding枚举还有很多其他的成员,对于不同的编码content-type可以有选择的应用

(3)后来我发现无论是content-type是gb2312还是utf-8,用

StreamReader sr = new StreamReader(stream , Encoding.Default );

都可以返回正常的汉字,所以统一的改成Encoding.Default



最后,在服务器端从一个url获得网页的源代码的代码如下:

/// <summary>
/// post一个指定的url,获得网页的源代码(用WebRequest实现)
/// </summary>
/// <param name="url"></param>
/// <returns>
/// 如果请求失败,返回null
/// 如果请求成功,返回网页的源代码
/// </returns>
public static string GetContentFromUrl2( string url )
{
    
//变量定义
    string respstr;

    WebRequest myWebRequest
=WebRequest.Create(url);
    
//            myWebRequest.PreAuthenticate=true;
    
//            NetworkCredential networkCredential=new NetworkCredential( username , password , domain );
    
//            myWebRequest.Credentials=networkCredential;

    
// Assign the response object of 'WebRequest' to a 'WebResponse' variable.
    WebResponse myWebResponse=myWebRequest.GetResponse();
    System.IO.Stream stream 
= myWebResponse.GetResponseStream();
    StreamReader sr 
= new StreamReader(stream , Encoding.Default );
    
//以字符串形式读取数据流
    respstr = sr.ReadToEnd();
    sr.Close(); 
    
    
return respstr;
        
}


问题终于解决拉

posted on 2006-02-16 17:25  今夜太冷  阅读(6920)  评论(1编辑  收藏  举报