前言

  今天在测试爬虫项目时,发现了一个很严肃的问题,当爬取的网页编码格式为gb2312时,按照一般的办法转化为utf-8编码时总是乱码,PS:爬取的所有网页无论何种编码格式,都转化为utf-8格式进行存储。

一、问题出现

  使用这篇文章里面的方法可以直接爬取页面信息并保存至本地使用Httpclient实现网页的爬取并保存至本地,当爬取这个网页时http://stock.10jqka.com.cn/zhuanti/hlw_list/,发现使用之前(未知编码 -> utf-8编码)的转化方式总是乱码。于是乎查阅了不少资料,发现都不是太适用。最后自己摸索出了一个解决办法,也特此记录。

二、解决方案

  1. 将gb2312格式转化为gbk格式

  2. 将gbk格式转化为utf-8格式

  这里的转化需要使用gbk作为一个中间格式,作为转化桥梁。

三、具体思路

  1. 当打开http://stock.10jqka.com.cn/zhuanti/hlw_list/这个链接,我们查看源码会发现编码格式为gb2312,如下图所示

  

  2. 由于本项目之前就已经使用了转化方案,但是此转化方案对网页为gb2312格式无效,本项目之前的转化方案的核心源代码为: 

public void getContent(String url) {
this.get = new HttpGet(url);
HttpResponse response = client.execute(this.get);
HttpEntity entity = response.getEntity();
byte[] bytes = EntityUtils.toByteArray(entity);
String content = new String(bytes);
// 默认为utf-8编码
String charset = "utf-8";
// 匹配<head></head>之间,出现在<meta>标签中的字符编码
Pattern pattern = Pattern.compile("<head>([\\s\\S]*?)<meta([\\s\\S]*?)charset\\s*=(\")?(.*?)\"");
Matcher matcher = pattern.matcher(content.toLowerCase());
if (matcher.find()) {
charset = matcher.group(4);
}
// 将目标字符编码转化为utf-8编码
String temp = new String(bytes, charset);
byte[] contentData = temp.getBytes("utf-8");
return contentData;
}

  这种方案对gb2312转化后还是乱码,之后的解决方案核心源代码为:  

public void getContent(String url) {
this.get = new HttpGet(url);
HttpResponse response = client.execute(this.get);
HttpEntity entity = response.getEntity();
byte[] bytes = EntityUtils.toByteArray(entity);
String content = new String(bytes);
// 默认为utf-8编码
String charset = "utf-8";
// 匹配<head></head>之间,出现在<meta>标签中的字符编码
Pattern pattern = Pattern.compile("<head>([\\s\\S]*?)<meta([\\s\\S]*?)charset\\s*=(\")?(.*?)\"");
Matcher matcher = pattern.matcher(content.toLowerCase());
if (matcher.find()) {
charset = matcher.group(4);
if (charset.equals("gb2312")) {
byte[] gbkBytes = new String(bytes, "gbk").getBytes();
return new String(gbkBytes, "utf-8").getBytes();
}
}
// 将目标字符编码转化为utf-8编码
String temp = new String(bytes, charset);
byte[] contentData = temp.getBytes("utf-8");
return contentData;
}

  通过这种方式我们就可以解决gb2312编码转化为utf-8编码时出现的乱码问题。

四、总结

  多思考,多动脑,这里只是给出了一个工程解决方案,并没有深入到其中的原理,由此问题可以引申出很多有意思的问题,如,utf-8、gbk、gb2312的编码方式怎样的?为什么这样转化就可以解决问题?这些问题值得我们去深入研究。由于本篇文章主要是讲工程解决方案,感兴趣的读者可以去深入了解。谢谢各位园友观看~

  附送一篇关于爬虫乱码问题解决的很好的文章,网络爬虫的乱码处理 ,讲得很不错,有做爬虫的园友遇到这一部分的问题时可以好好参考参考。

【知识积累】爬虫之网页乱码解决方法(gb2312 -> utf-8)的更多相关文章

  1. html乱码原因与网页乱码解决方法

    造成html网页乱码原因主要是html源代码内中文字内容与html编码不同造成.但无论是哪种情况造成乱码在网页开始时候都需要设置网页编码. charset编码设置 html网页乱码效果截图 一.乱码造 ...

  2. Python使用request包请求网页乱码解决方法

    使用requests请求网页时,返回的页面信息有时是乱码,如下代码 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) App ...

  3. python积累二:中文乱码解决方法

    根据网上提供的解决方法:添加#coding=utf-8或# -*- coding: utf-8 -*- #coding=utf-8 print "还不行?" 执行结果:还是乱码!: ...

  4. QT编写的网页浏览器网页乱码解决方法

    1.如果是本地网页,可以将网页编码改为GB2312 <meta http-equiv="Content-Type" content="text/html; char ...

  5. php mysql 中文乱码解决方法

    本文章向码农们介绍php mysql 中文乱码解决方法,对码农们非常实用,需要的码农可以参考一下. 从MySQL 4.1开始引入多语言的支持,但是用PHP插入的中文会出现乱码.无论用什么编码也不行 解 ...

  6. MySql数据库乱码解决方法

    MySql数据库乱码解决方法 解决乱码问题一个原则:存取系统使用一致的编码规则. 多使用mysql的原生命令行,这样才能做更多的事情. ​ 第一步: 确认应用系统需要使用的编码 java的默认编码是跟 ...

  7. gvim的菜单乱码解决方法

    gvim的菜单乱码解决方法: (乱码是由于系统内码不兼容导致,系统内码包括gb2312 gb18030 utf-8 utf-16[unicode]等) 生成文件 ~/.gvimrc 并添加如下语句:s ...

  8. jquery的ajax()函数传值中文乱码解决方法介绍

    jquery的ajax()函数传值中文乱码解决方法介绍,需要的朋友可以参考下 代码如下: $.ajax({ dataType : ‘json', type : ‘POST', url : ‘http: ...

  9. ueditor的工具栏显示乱码解决方法 小问题.. 是你的页面编码与语言包js编码不符所导致的

    ueditor的工具栏显示乱码解决方法 小问题..  是你的页面编码与语言包js编码不符所导致的解决方法:用记事本将ueditor\..\lang\zh-cn\zh-cn.js打开,然后保存为ANSI ...

随机推荐

  1. 【C++】自绘控件基础

    由于我们对控件的功能.外观的需求,公共控件并不能很好地满足这一点,所以我们就得自绘控件. 自绘控件有许多方法,比如:处理WM_PAINT消息,设置ownDraw风格,处理WM_CTLCOLOR消息,等 ...

  2. Amazon RDS MySQL数据库还原时 log_bin_trust_function_creators 错误解决办法

    使用了Amazon AWS EC2免费云空间,数据库实例采用Amazon RDS.原来在Windows Server上有一个存在大量数据的MySQL数据库.现在需要在Amazon RDS上还原这个My ...

  3. Ubuntu Server 15.04的安装

    U盘启动工具的制作就跟Windows系统以及Linux各版本的desktop版不同,用的工具也是我第一次见到的“Win32_Disk_Imager”(点击下载) 安装过程请参考:http://www. ...

  4. Java设计模式10:观察者模式

    观察者模式 观察者模式也叫作发布-订阅模式,也就是事件监听机制.观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态上发生变化时,会通知所有观察者对象,使他 ...

  5. Aoite 系列 目录

    介绍 本项目从2009年孵化(V->Sofire->Aoite),至今已度过5个年头.一直在优化,一直在重构,一直在商用.有十分完整的单元测试用例.可以放心使用. Aoite on 博客园 ...

  6. Aoite 系列(04) - 强劲的 CommandModel 开发模式(上篇)

    Aoite 是一个适于任何 .Net Framework 4.0+ 项目的快速开发整体解决方案.Aoite.CommandModel 是一种开发模式,我把它成为"命令模型",这是一 ...

  7. Ng Http Request/response格式转换

    angular作为Single Page Application推荐的交互方式当然是基于json的ajax调用.但今天要说的是当你不幸工作在一个遗留或者不可控制的服务上,而这服务是基于非json提交方 ...

  8. 通过分析iframe和无阻塞脚本关系能让我们更懂iframe

    在我上篇文章里,我提到一种使用iframe完成无阻塞脚本加载的方式,因为我对iframe的偏见很大,所以上篇文章里我没有展开讨论这个问题. 文章发表后有位网友问了我这样一个问题,下面是他问题的原文,如 ...

  9. 赴美工作常识(Part 6 - 绿卡排队)

    上一篇<赴美工作常识(Part 5 - 绿卡优先级)>解释完排队的优先级是怎么确定的,以及 PERM 和 I–140 表的意义,接下来就要解释一下队具体是怎么排的以及排到之后的 I–485 ...

  10. 当pageIndex遇上pageNo

    我们的项目程序里,由于赶项目进度,同时,大家缺乏相应的沟通,在服务层提供的接口里,涉及到分页查询的,有如下三种情形: l  List<OrderInfo> GetOrderList(Ord ...