.net UTF-8 转换 GB2312 出错

dengkecn 2010-03-28 10:49:14
我的网站是GB2312的,抓取了一个UTF-8的网页内容,存放到strPage中,得到的是乱码,经过下面的转换,得到正确的GB2312内容:

Encoding utf8 = Encoding.UTF8;
Encoding gb2312 = Encoding.GetEncoding("gb2312");

byte[] buffer = gb2312.GetBytes(strPage); //还原byte[]
strPage= utf8.GetString(buffer); //重新解码

基本上没问题。不过,原页面中有一串
“<span class="link_g_12"> 编辑:梁璠 来源:中关村在线</span>”
经过我的转换,总是变成
“<span class="link_g_12"> 编辑:梁璠 来源:中关村在?/span>”

这阻碍了我对文本进行进一步的分析。头痛ing,有没有高手帮忙解决这个问题?
...全文
519 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
dengkecn 2010-03-29
  • 打赏
  • 举报
回复
我觉得既然我们讨论的问题都已经这么集中了,而且彼此都接得上,就说明在这个话题上,该用哪几行代码抓取网页HTML,彼此都是明白的,我也不必吝惜,你也不必故意少写一个东西。

或者我该问:在抓取网页HTML的时候,能不能直接抓到bytes[]。
我想,如果有问题发生的话,应该就是在抓取网页的时候,后台根据web.config的规定,自动对抓取内容进行了一次GB2312编码,抓到了原本该是UTF-8的乱码。

如果错误发生在这里,后面再编来编去,都已经变不回来了。
dengkecn 2010-03-29
  • 打赏
  • 举报
回复
re#11楼,我也不是吝惜,因为这段代码实在也没啥特别的,我的代码如下:

HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(strUrlDecode);
myRequest.Timeout = 60000;
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream myStream = myResponse.GetResponseStream();
StreamReader mySr = new StreamReader(myStream, Encoding.Default);
string strSearchPage = mySr.ReadToEnd();
myStream.Close();

而是你没有了解我说的重点。
我的重点是:你的代码的第3行,和我的代码的第6行,得到的结果,是已经经过GB2312编码的,因为我的web.config里面规定了默认的编码是GB2312,这样你明白了吗?

如果抓取的页面是UTF-8的,你的代码中的ss获得的内容,中文全是乱码。你可以自己试一下,前提是web.config里面规定默认编码为GB2312。
dengkecn 2010-03-28
  • 打赏
  • 举报
回复
比如,抓取http://digi.hsw.cn/system/2010/03/26/050469479.shtml这个网页的内容,要得到文章内容和出处,内容抓下来以后,经过字符串分析,得知它是UTF-8的,因此所有中文都是乱码,不能用。

转>>byte>>转UTF-8以后,几乎所有中文都正确得到了,就是出处那里,出了点小问题
dengkecn 2010-03-28
  • 打赏
  • 举报
回复
可能是我没说清楚。
我的网站,在web.config里面定义了:<globalization uiCulture="zh-CN" culture="zh-CN" requestEncoding="gb2312" responseEncoding="gb2312" fileEncoding="gb2312"/>

我抓取网页的代码,如你所说,不到10行代码,只有7行,就是用HttpWebRequest、HttpWebResponse连接,用Steam、StreamReader得到内容,这个并没有什么问题。得到内容的过程也没什么问题,整个网页的编码转换,也几乎没有问题,就是除了“<span class="link_g_12"> 编辑:梁璠 来源:中关村在?/span>"这一句。

我的意思是,在web.config里面定义了整个网站是gb2312的,那么网站里面的每一个aspx,没有特殊说明的话,都是gb2312的。它的cs后台在抓区别的网站页面的时候,如果抓到UTF-8的网页,得到的是乱码,是因为它对抓来的内容进行了GB2312编码,编码不对,自然就乱码了。

因此,首先要对内容进行反GB2312编码,变成byte,然后再从byte变到UTF-8。

这里面有几个编码过程:后台自动对抓取内容进行GB2312编码 >> 程序把它转成byte >> 程序把byte转成UTF-8,在某个编码过程中,可能造成了部分损失或错误,致使结果不能100%正确。

我想解决的是这个问题,而不是整个编码过程编反掉的问题。
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 dengkecn 的回复:]
因此思路应该是:用GB2312抓取网页 >> ........如果我用UTF-8抓取.......
[/Quote]

什么是“用xxx抓取网页”?至少描述得稍微可操作性一些。
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 dengkecn 的回复:]
后来查资料才搞明白,我的网站是GB2312的,在后台抓取的时候,得到的页面内容就已经是经过GB2312编码的了,如果抓取的网页是UTF-8的,才会乱码。[/Quote]

什么“资料”?你的网站的所谓编码跟你抓取的html有什么关系?一个网站的不同的页面的也是可以输出编码各不相同的,难道不看具体的做法而看什么“网站”?

具体来说,你是如何抓取的?

抓取html只需要不到10行代码,贴出代码来!
dengkecn 2010-03-28
  • 打赏
  • 举报
回复
回复#1:

没有反。我原来也是用utf8.GetBytes(strPage),得到的还是乱码。后来查资料才搞明白,我的网站是GB2312的,在后台抓取的时候,得到的页面内容就已经是经过GB2312编码的了,如果抓取的网页是UTF-8的,才会乱码。

因此思路应该是:用GB2312抓取网页 >> 分析其编码是GB2312还是UTF-8 >> 如果原页面是UTF-8,则把抓取到的内容还原成byte >> 然后再转化成UTF-8,这样才能得到原本的内容。

回复#2:

由于抓取的网页是不固定的,不知道是GB2312还是UTF-8,抓下来以后,经过分析才知道该网页是什么编码。如果我用UTF-8抓取,如果网页是GB2312的,一样还是得到乱码,还是要转编码。你的意识是如果是UTF-8德,重新抓一次吗?那样没效率吧?
jshi123 2010-03-28
  • 打赏
  • 举报
回复
抓取时就用utf8
  • 打赏
  • 举报
回复
反了吧?如果读取utf8的,应该用utf8.GetBytes(strPage)。
「已注销」 2010-03-28
  • 打赏
  • 举报
回复
学习!回复内容太短了!
  • 打赏
  • 举报
回复
唉,说来说去,我还不不知道你把个抓取代码跟你别的aspx编码能够有什么关系呢?

既然你那么吝啬贴上你的代码,我贴几条:
var x = (HttpWebRequest)WebRequest.Create("http://digi.hsw.cn/system/2010/03/26/050469479.shtml");
var y = x.GetResponse();
var ss = new StreamReader(y.GetResponseStream()).ReadToEnd();
var 你要的部分 = ss.Substring(24300, 80);


你在这个上面修改一下,说明你的跟这个有什么区别?(肯定有区别的,我故意少写了一个东西)
jshi123 2010-03-28
  • 打赏
  • 举报
回复
看下你的代码
dengkecn 2010-03-28
  • 打赏
  • 举报
回复
Re #8楼:

我试了你上面的代码,会在这句出错:
Encoding encoding = Encoding.GetEncoding(resp.ContentEncoding);

错误:
异常详细信息: System.ArgumentException: “”不是受支持的编码名。

说明没有抓到页面的编码。

而用
StreamReader sr = new StreamReader(resp.GetResponseStream(), true);
则抓到的页面内容是空的。
jshi123 2010-03-28
  • 打赏
  • 举报
回复
可以在构造StremReader的时候根据抓到的页面的编码指定encoding:

HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://www.sina.com.cn");
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Encoding encoding = Encoding.GetEncoding(resp.ContentEncoding);
StreamReader sr = new StreamReader(resp.GetResponseStream(), encoding);


也可以在构造StreamReader的时候,让他根据页面的前3字节顺序标记(BOM)来自动识别UTF8或Unicode编码的页面:
StreamReader sr = new StreamReader(resp.GetResponseStream(), true);

62,267

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧