字符编码的概念及字符编码的探测

EncodingDetect.java 由于文件编码类型众多,例如UTF-8,GBK,UTF-16,GB2312等等,识别文件编码类型,使用方法参考此文:http://blog.youkuaiyun.com/21aspnet/article/details/50612867 立即下载


1 关于多字节与宽字符的解释

非英语系的大部分语言,存在无法用有限的ascii字符表达的问题。由此产生了使用多字节字符来表示的办法,比如GB编码的汉字。

但多字节带来的一个显著不便就是多字节字符在处理的时候不太方便。比如文本编辑的时候,中英文混排,光标移动、汉字删除时会出现半个汉字的问题。
为了文本处理的方便,许多系统内部采用了将多字节字符和单字节字符都转换称宽字符的办法,将所有的字符都变成等宽,一切都方便了。

在中文windows中,内码为GBK,而在Linux中,内码为utf32 。这样VC在中文系统下的wchar_t为2字节,GCC在Linux系统下wchar_t为4字节。


2 代码中的中文字符编码

2.1 C++源码中的中文

如果是多字节字符串,则编译器按照源文件的编码,对文件中的字符串进行处理,将字符硬编码到可执行文件中,在执行时,输出也直接输出此编码。这样有一个缺点,不同的字符使用不同的长度,操作效率不高。优点是,字符串占用内存空间小。

如果是使用wchar_t类型宽字符串,在常量字符串前加L"中国",这样编译器会根据系统代码页的编码,对源码字符串转换为UTF16(Win)/UTF32(Linux)的宽字符,然后硬编码到可执行程序中。这样,所有字符串均为等长编码;但采用这种作法,VC只能处理GBK编码的源文件,而GCC只能处理UTF8的源文件件。

采用上面策略处理的程序,如果在另外一个编码环境下执行,就会以错误的Locale来解码,界面或输出出现乱码。一种比较笨拙的办法,就是根据不同的系统环境,执行源码中编码到目的系统的编码的编码转换。这通常会比较笨拙,难以较好的实现国际化。较好的办法是不依赖本地的Locale编码,只使用标准编码之间的转换。

因此在Win平台下,淘汰多字节,只用宽字符。将所有字符串增加L宏,更好的办法是_T()宏。这样,如果是Unicode编译,就直接编码成UTF16。

在Linux下就不存在这个问题,由于在Linux版本均使用UTF8编码,编码转换均为UTF8到UTF32。

在Java和Python中,内码均Unicode。同时这些语言都有自己的解释器,解释器会将源代码中的字符都统一编码为Unicode在虚拟机内部统一使用。

2.2 Python源码中的中文

源代码文件可以是各种编码格式,如果不是UTF8,需要在源码的第一行指明:#-*-coding:gbk-*-;这样编译器会将源文件进行转换,从文件自身的编码转换为第一行指定的编码,然后再对源码文件进行解释执行。

#-*- coding:utf8 -*-
import sys
import os
print(sys.getdefaultencoding())
print(sys.stdout.encoding)
print(sys.stdin.encoding)

s = "中国ABAB"
print(s)

print(s.encode("utf8"))
print(s.encode("gbk"))

   输出  

utf-8
cp936
cp936
中国ABAB
b'\xe4\xb8\xad\xe5\x9b\xbdAB\xef\xbc\xa1\xef\xbc\xa2'
b'\xd6\xd0\xb9\xfaAB\xa3\xc1\xa3\xc2'

2.3 Java源码中的中文

类似于 Python

	public static void testSrcCode()
	{		
		String s = "中国ABAB";		
		int len = s.length();		
		
		for(int i=0; i<s.length();i++)
		{			
			System.out.print(s.charAt(i));
			System.out.printf(" code point: 0x%1$x\n",s.codePointAt(i));
		}
		System.out.println("-----------------------------------");
		try 
		{
			System.out.print("UTF8: ");
			byte[] bt = s.getBytes("utf8");
			for(int j = 0;j < bt.length ;j++)
			{
				System.out.printf("0x%1$x ",bt[j]);
			}
			System.out.println();
		} 
		catch (UnsupportedEncodingException e) 
		{			
			e.printStackTrace();
		}
		System.out.println("-----------------------------------");
		try 
		{
			System.out.print("GBK: ");
			byte[] bt = s.getBytes("gbk");
			for(int j = 0;j < bt.length ;j++)
			{
				System.out.printf("0x%1$x ",bt[j]);
			}
			System.out.println();
		} 
		catch (UnsupportedEncodingException e) 
		{			
			e.printStackTrace();
		}
		System.out.println("-----------------------------------");
		
		try 
		{
			System.out.print("UTF16: ");
			byte[] bt = s.getBytes("utf16");
			for(int j = 0;j < bt.length ;j++)
			{
				System.out.printf("0x%1$x ",bt[j]);
			}
			System.out.println();
		} 
		catch (UnsupportedEncodingException e) 
		{			
			e.printStackTrace();
		}
	}

输出 

中 code point: 0x4e2d
国 code point: 0x56fd
A code point: 0x41
B code point: 0x42
A code point: 0xff21
B code point: 0xff22
-----------------------------------
UTF8: 0xe4 0xb8 0xad 0xe5 0x9b 0xbd 0x41 0x42 0xef 0xbc 0xa1 0xef 0xbc 0xa2 
-----------------------------------
GBK: 0xd6 0xd0 0xb9 0xfa 0x41 0x42 0xa3 0xc1 0xa3 0xc2 
-----------------------------------
UTF16: 0xfe 0xff 0x4e 0x2d 0x56 0xfd 0x0 0x41 0x0 0x42 0xff 0x21 0xff 0x22 


2.4 BOM

文本文件头不同编码的标记,称为BOM,存储的时候可以指定为NO BOM,可以去掉此头。

UTF编码

BOM

UTF-8

EF BB BF

UTF-16LE     

FF FE

UTF-16BE

FE FF

UTF-32LE

FF FE 00 00

UTF-32BE

00 00 FE FF

3 中文编码历史 

在中文编码的历史上,在GB出现以前,已经存在一些汉字内码表示。所谓 内码即机内编码汉字的方法。为了便于不同内码系统之间的信息交换,国家定制了交换码。

在1980年,国家制定了GB2312,收集了约7K多个常用汉字。值得一提的是,GB2312使用了所谓的区位码的编码方法,但为了使得每个字节与ASCII编码区分,对每个字节(区码和位码)都增加了0xA0,即160。从这里可以看出,GB2312并没有编码ASCII字符及标点。

后续1995年又制定了GBK(CP939稍有差异)标准,为两字节编码 ,兼容GB2312,收集了2W多个汉字。同时也将ASCII字母及标点符号进行了编码,这样导致这些符号是两字节的,在显示的时候就是所谓的全角符号,直观看起来就是比较大。而英文模式下的字母和符号即为半角。

在unicode3.1标准出现之后,国家又制定了GB18030,其继续兼容 GBK ,并采用变长编码,将所有unicode字符均映射了一遍。和UFT8一样,采用了多字节编码。


4 中文显示原理

操作系统支持内码的字体集文件,内容为汉字的点阵信息,其可能按Unicode编码/内码进行索引。对于文件中的文字,首先转换成内码/unicode,按照查看字体文件,将点阵信息发送到显卡上。

操作系统提供了一个造字程序,可以选择一个编码,然后画出其字的点阵图,最后和字体文件进行链接。这样的特殊字符只能通过系统的特殊字符表来复制使用。

更进一步可以导入输入法表进行编辑,使得可以通过输入法来输出造的特殊字符。下图是随意造了一个三个羊组成的汉字,指定其Unicode编码为AAA1。


5 编码的探测
对于浏览器,在工具或查看中会有一个编码的选项,可以勾选为自动探测,这样当我们访问不同编码的网站时,浏览器会帮我们进行选择,而不用当出现乱码时,由我们去猜测并手工设定。下面介绍3个开源项目,可以实现检测一段输入的编码格式。
最早Mozilla开源了chardet项目,它用来对于输入进行分析,返回输入字节流的编码方式。其原理为
http://www-archive.mozilla.org/projects/intl/UniversalCharsetDetection.html 
jchardet是一个基于chardet的java移植,cpdetector则是一个java探测框架,其中集成了jchardet的探测实现。
其他相应的移植还有python pchardet和C# nuniversalchardet项目。
下面介绍一下原理

5.1 编码方案法 
当分析编码时,如果遇到了某种编码的非范围内的码点,则说明不是这种编码。
针对每种编码都设计一个检查状态机,对输入依次执行这些状态机。典型情况下,一个状态机将提供一个肯定的回答,而其他状态机返回一个否定的回答。对于不同编码的重叠字符,则此方法无能为力。例如EUC-CN与EUC-KR之间有较多的重叠编码。
其特点是性能高,适合处理多字节编码,不适合处理单字节的,遇到重叠字符集时比较尴尬。

5.2 字符分布
在不同的语言中,存在着使用最为广泛的字,通过检测这些最广泛使用字来猜测源的编码。对于CJK字符比较有用。对于中文来说,最常用的256个汉字的CDF为61%,而4096个常用汉字则为99%。对于日文,最常用的128个字的CDF为77%。对于韩文为79%。也就是说很小集合的字的码点覆盖了较大比例的文字。能较好的解决编码重叠字符的问题。为了得到特定语言编码中字母的分布情况,需要进行一定的统计计算。

一个简化版本是:分布率 = 最常见的512个字的出现次数/其余字母的出现次数。例如对于GBK编码,在level1的3775个汉字中,最常见的512个汉字覆盖了文本中的79%的出现,当处理一个样本时,理论上应该得到分布率为 0.79/0.21=3.8;对于随机产生的文本,则分布率为512/3243 = 0.16,如果加入LEVEL2的汉字,这个比例会更小。对于日文这两个数字为12.58 / 0.19 ,韩文为73.24 / 0.28
置信度的计算:对于输入文本进行统计,计算实际分布率/理论分布率。
其特点是非常适合多字节编码,高效,但只适应于典型的文本(文本内容小时难以有效)。
5.3 两字符序列分布
对于字母类的语言,如果只有很少的元素组成了大量的单词。则不能用上面第二种方法,使用2字母的顺序的分布情况来分析。对于探测单字节语言比较有用。
例如,对于俄语,对大量文本进行分析,对于所有的两字母序列出现计数为20134122,其中1961个序列出现率比其他的低3倍,称1961个序列为此语言的负序列。通过计算,也可以得到置信度。计算算法没看明白。
其特点是适合单字节编码,对多字节效率差
5.4 组合方法
结合以上三种方法,得到一种最可信的结果。伪码如下:
Charset AutoDetection (InputText)
{
 if (all characters in InputText are ASCII)
 {
  if InputText contains ESC or ~{
  {
   call ISO-2022 and HZ detector with InputText;
   if one of them succeed, 
    return that charset, 
   otherwise 
    return ASCII;
  }
  else
   return ASCII;
 }
 else if (InputText start with BOM)
 {	
  return UCS2;
 }
 else
 {
  Call all multi-byte detectors and single-byte detectors;
  Return the one with best confidence;
 }
}
5.4 字符探测实践

下面介绍如何利用cpdector框架来进行编码探测。框架提供了一个CodepageDetertorProxy类,其为单例类。通过这个类的对象,为其添加各种解码实现对象,然后调用其提供的detectCodepage()方法即可。

import java.io.*;
import java.net.*;
import info.monitorenter.cpdetector.io.*;

class ChardetWrapper 
{
	// Create the proxy:
	CodepageDetectorProxy detector = CodepageDetectorProxy.getInstance(); // A singleton.

	// constructor:
	public ChardetWrapper() 
	{
		// Add the implementations of
		// info.monitorenter.cpdetector.io.ICodepageDetector:
		// This one is quick if we deal with unicode codepages:
		detector.add(new ByteOrderMarkDetector());
		// The first instance delegated to tries to detect the meta charset
		// attribut in html pages.
		detector.add(new ParsingDetector(false)); // be verbose about parsing.
		// This one does the tricks of exclusion and frequency detection, if
		// first implementation is
		// unsuccessful:
		detector.add(JChardetFacade.getInstance()); // Another singleton.
		detector.add(ASCIIDetector.getInstance()); // Fallback, see javadoc.		
	}

	public boolean parseUrl(String url) throws MalformedURLException, IOException 
	{
		boolean ret = false;
		// Work with the configured proxy:
		java.nio.charset.Charset charset = null;
		charset = detector.detectCodepage(new URL(url));
	    if(charset == null)
	    {
	       System.out.println("bogus document");
	    }
	    else
	    {
	    	System.out.println(charset.toString());
	        // Open the document in the given code page:	        
	        // Read from it, do sth., whatever you desire. The character are now - hopefully - correct..
	        ret = true;
	    }
	    return ret;
	}
	
	public boolean parseFile(String file) throws MalformedURLException, IOException 
	{
		boolean ret = false;
		// Work with the configured proxy:
		java.nio.charset.Charset charset = null;
		FileInputStream fis = new FileInputStream(file);
		BufferedInputStream bis = new BufferedInputStream(fis);

		charset = detector.detectCodepage(bis,10240000);
	    if(charset == null)
	    {
	       System.out.println("bogus document");
	    }
	    else
	    {
	    	System.out.println(charset.toString());
	        // Open the document in the given code page:	        
	        // Read from it, do sth., whatever you desire. The character are now - hopefully - correct..
	        ret = true;
	    }
	    return ret;
	}	
}

public class CpdetTest 
{
	public static void main(String[] args) 
	{				
		ChardetWrapper u = new ChardetWrapper();
		String url = "http://www.sina.com";
		//String path = "C:/字幕/007:来自俄罗斯的爱情.ass";
		try 
		{
			//u.parseFile(path);
			u.parseUrl(url);
		}
		catch (Exception e) 
		{			
			e.printStackTrace();
		}		
	}
}
也可以直接使用jchardec来进行探测,其要求继承ChardetObserver接口,并实现notify方法,库会在探测成功后通过notify方法将结果传出来。
import java.io.*;
import java.net.*;
import java.util.*;

import org.mozilla.intl.chardet.*;

class myChardecObserver implements nsICharsetDetectionObserver 
{
	public void Notify(String charset) 
	{
		CharsetDetectorTest.found = true;
		System.out.println("CHARSET = " + charset);
	}
}

public class CharsetDetectorTest {

	public static boolean found = false;

	public static void main(String argv[]) throws Exception {

		// Initalize the nsDetector() ;
		int lang = (argv.length == 2) ? Integer.parseInt(argv[1]): nsPSMDetector.ALL;
		nsDetector detector = new nsDetector(nsPSMDetector.ALL);

		// Set an observer...
		// The Notify() will be called when a matching charset is found.

		detector.Init(new myChardecObserver());

		URL url = new URL("http://www.sina.com//");		
		BufferedInputStream bis = new BufferedInputStream(url.openStream());
		
		//FileInputStream fis = new FileInputStream("C:/字幕/007:来自俄罗斯的爱情.ass");
		//BufferedInputStream bis = new BufferedInputStream(fis);
		byte[] buf = new byte[512];
		int len;
		boolean done = false;
		boolean isAscii = true;		

		while ((len = bis.read(buf, 0, buf.length)) != -1 ) 
		{			
			//System.out.printf("Read byte %d\n",len);
			// Check if the stream is only ascii.
			if (isAscii)
				isAscii = detector.isAscii(buf, len);

			// DoIt if non-ascii and not done yet.
			if (!isAscii && !done)
				done = detector.DoIt(buf, len, false);
			
		}
		detector.DataEnd();

		if (isAscii) 
		{
			System.out.println("CHARSET = ASCII");
			found = true;
		}

		if (!found) 
		{
			String prob[] = detector.getProbableCharsets();
			for (int i = 0; i < prob.length; i++) 
			{
				System.out.println("Probable Charset = " + prob[i]);
			}
		}
	}
}




i.MX RT1064引脚配置与BGA封装选型实战指南 在嵌入式硬件设计中,引脚配置与PCB布局是连接芯片手册与物理实现的关键桥梁,直接影响系统的稳定性与信号完整性。其核心原理在于理解处理器的IOMUX(输入/输出多路复用器)系统与多电源域架构,前者通过软件配置实现引脚功能的灵活复用,后者则为不同外设接口提供独立的电压基准,是保障电源稳定性的基石。从技术价值看,合理的引脚规划能规避信号干扰、电源不稳等潜在风险,提升设计一次成功率。在应用场景上,无论是连接SDRAM、USB、SDIO等高速外设,还是配置UART、I2C等中低速接口,都需要遵循特定的布局布线规则。本 阅读详情

相关推荐

【破局之道】LangChain4j 0.31.0 + Java 8 + Spring Boot:在“过时”环境中构建本地大模型应用的实战指南

本文为使用Java 8和Spring Boot等“过时”技术栈的团队提供了构建本地大模型应用的实战指南。通过采用LangChain4j 0.31.0这一兼容版本,结合Ollama部署本地大模型,开发者无需升级JDK即可在现有项目中快速集成AI能力,实现智能问答、文档摘要等功能,为传统项目注入创新活力。

t4y5u6i7o的博客 557

一个识别文件的工具

cpdetector是一个识别文件的工具。常用的utf - 8 ,还有GBK,都能够很好的识别,可以到官网上下载最新的jar包,一定要将cpdetector_1.0.8.jar,antlr-2.7.4.jar,还有chardet-1.0.jar引入其中。 CodepageDetectorProxy detector = CodepageDetectorProxy.getInstanc...

slow is fast 312

深交所 vs 上交所:Level-2实时数据推送规则详解与策略适配指南

本文深度解析沪深Level-2实时数据推送规则的关键差异,包括逐笔成交、逐笔委托和10档行情接口的处理逻辑。针对高频交易策略,详细对比上交所与深交所在数据推送机制、时间戳处理及委托队列解析等方面的差异,并提供具体的策略适配方案和性能优化建议,帮助量化投资者提升跨市场交易稳定性。

weixin_27310417的博客 1165

Java判断文件编码的方式 cpdetector(第三方库)

动态获取文件的编码格式

dumuzhouguohe的博客 1509

MatLab Desired port was :31515解决方案

前言:使用的MatLabR2022b今天突然出现了错误,在程序中打不开文件。后尝试了下面的方法,可以解决。后面还有另一种方法,上面方法如果行不通,大家可以尝试一下。搜索栏输入:firewall.cpl。找到相关项,右键属性,设置为允许。

qq_42212501的博客 1339

单片机通识之UART通信协议(如何用汇编实现)

使用汇编实现UART通信

smart_num_1的博客 996

python字符编码转换_python-字符编码转换

PYTHON编码类型默认是UTF-8,然而在工作中经常会遇到不同编码的问题,这时就需要对不同的编码进行转换,在python中不同编码的转换都要经过Unicode,不论是UTF-8或者是GBK,整个过程都是先通过编码decode转换为Unicode告诉Unicode当前的编码格式是什么、然后再通过解码encode转换为自己想要实现的编码格式或类型。FOLLOW ME YS2019转码流程1、#-*-...

weixin_39977586的博客 503

宝塔面板磁盘扩容后不生效?5步搞定Linux服务器磁盘空间更新(附详细命令)

本文详细解析了Linux服务器磁盘扩容后宝塔面板显示不生效的常见问题。通过理解磁盘、分区、文件系统三层逻辑,提供5步解决方案:检查磁盘状态、安装growpart工具、扩展分区、使用resize2fs命令扩展文件系统,并最终验证结果。文中附有详细命令和针对XFS、LVM等进阶场景的指南,帮助用户彻底解决磁盘空间更新问题。

weixin_29271263的博客 128

字符编码检测和处理

由于字符编码经常导致一些异常问题,而且不是很好定位,一直是写健壮性代码的困惑之一。为此我在调研开源的cpdelector等基础上进行封装,实现了文本文件编码检测和字符串的编码检测,以及统一的文本字符处理,方便了程序调用的使用,以供大家参考。      测试程序如下,改造工程见附件! UserTextDelector .java package cpdetector; import

龙行天下的专栏 1696

MobaXterm破解14个会话限制的保姆级教程(附Python环境配置指南)

本文提供了MobaXterm破解14个会话限制的详细教程,并深入讲解了如何配置稳定的Python环境以支持相关脚本运行。通过理解软件授权机制、安全实践步骤以及许可文件的应用,帮助用户解除会话数量限制,实现高效的远程服务器管理与自动化运维。

weixin_29211309的博客 1645

军品研制过程-转阶段

介绍军品转阶段评审

Abel的博客 2万+

简单自动获取文件编码

前段时间,在文章中用到读取文件,由于文件的编码不同,需要在程序中不断的调整读取文件的编码格式。 BufferedReader reader = newBufferedReader(newInputStreamReader(new FileInputStream(new File(文件名)),编码格式));          在网上找了一些资料,对他们总结一下,以备以后需要用的时候能够方

zhjw1006的专栏 437

51单片机 驱动有源/无源蜂鸣器+Proteus仿真

51单片机 驱动有源/无源蜂鸣器+Proteus仿真 相关篇《51单片机 Proteus仿真有源蜂鸣器始终不响原因及解决方法》 电路搭建 采用NPN管驱动有源蜂鸣器电路 采用PNP管驱动有源蜂鸣器电路 采用PNP管驱动无源蜂鸣器 采用NPN管驱动无源蜂鸣器 Proteus元器件列表 实例代码 /************************************************************************************* * 实验现象:下载程序

perseverance51博客 2万+

手把手教你写网络爬虫(8):彻底解决乱码问题

&#13; &#13; &#13; &#13; &#13; &#13; &#13; (点击上方公众号,可快速关注)来源: 拓海http://www.cnblogs.com/tuohai...

Python开发者 1261

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

[原创]手把手教你写网络爬虫(8):彻底解决乱码问题

手把手教你写网络爬虫(8) 作者:拓海(https://github.com/tuohai666) 摘要:从零开始写爬虫,初学者的速成指南! 封面: 字符编解码是爬虫里必学的一项知识,在我们的爬虫生涯中早晚会爬到乱码的网页,与其遇到时惊慌失措,不如早学早好,彻底避免乱码问题。 字符编码简介 什么是字符集 在介绍字符编码之前,我们先了解下什么是字符集。 字符(...

weixin_30622181的博客 395

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

xml如何探测字符编码

xml如何探测字符编码 之前一度以为,xml头部的字符声明部分,即: 可以轻易被parser解析,因为这部分可以保证全英文,都是基础的ascii字符,所有编码对这块兼容。 看了这篇帖子和xml规范才知道: 1、不是所有编码方式都是ascii基础字符兼容的 UTF-16 (LE/BE), UCS-2, UCS-4 and EBCDIC are all legal encodin

信言的笔记 1036

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

icu 字符编码探测及字符编码转换实例

icu 字符串编码探测及字符串编码转换实例 分类: 杂项2012-03-02 13:59 335人阅读 评论(0) 收藏 举报 bufferfilenulldelete存储 编译: g++ -o x x.cpp -licuuc -licui18n 请大家确认是否安装icu库 [cpp] view plaincopy #in

无与伦比BLOG 3019

java 探测 txt字符编码,jChardet探测文件字符编码

packagetest;importjava.io.BufferedInputStream;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.IOException;importorg.mozilla.intl.chardet.nsDet...

weixin_36154762的博客 251

java 探测 txt字符编码_Java自动探测文件的字符编码

import java.io.BufferedInputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import org.mozilla.intl.chardet.nsDetector;import ...

weixin_42131405的博客 115

Java自动探测文件的字符编码

import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import org.mozilla.intl.chardet.nsD...

dlxqlig0806的博客 108

对于爬虫字符编码出现错误的终极解决

对于爬虫字符编码出现错误的终极解决 文章目录对于爬虫字符编码出现错误的终极解决引言解决思路代码实现 引言 众所周知,网页在编写的时候,会采用不同的编码格式的,因此,在爬虫过程中,很容易就会出现字符编码的乱码的问题,这个问题是很令人烦恼的,但是,这里其实也有一个通用的方法来解决这个烦人的问题。 解决思路 我们想办法用一种通用的方法去直接获取到所要爬取的网页的具体编码格式,然后在根据这个编码格式进行转码即就可以了,从而也就避免了字符编码乱码的问题。 代码实现 (我们采用 Jupyter Notebook 来实现

江月的博客 1万+

字符编码和文件编码

1.字符编码 字符的编码格式在博文字符集&各种编码&编码解码中有详细介绍 2.文件编码 查看文件的编码格式 vim打开某个文件,:set fileencoding后回车,就能查看文件的编码了 要设置vim相关的编码格式可以修改~/.vimc文件,添加如下内容: :set encoding=utf-8 :set fileencodings=ucs-b...

abc25257759的博客 615

使用ICU进行字符集探测 文档译稿

使用ICU进行字符集探测文档译稿原文http://userguide.icu-project.org/conversion/detectionCharacter Set Detection 字符集探测Overview 概述       字符集探测是对未知格式的字符数据进行确定字符集或者编码的过程。这充其量是一个使用统计学和启发式方法进行的一项不精确的操作。也正因如此,如果可以提供一种语言的至少几

mingyuan's workspace 3558

vim字符编码详解

vim字符编码配置详解

u013511885的博客 3067

java使用cpdetecto 编码探测

在项目中加入 这几个包都在附件的cpdetector_1.0.8_binary.zip中 - cpdetector_1.0.8.jar - chardet.jar - antlr.jar /** * 文件流中 读取字节编码 * @param in * @return * @throws Exception * @throws...

iteye_8088的博客 289

java自动探测文件的字符编码

Mozilla有一个C++版的自动字符集探测算法代码,然后sourceforge上有人将其改成java版的~~ 主页:http://jchardet.sourceforge.net/ jchardet is a java port of the source from mozilla's automatic charset detection algorithm. The origina...

weixin_34293902的博客 87
上一篇: Squid代理服务3.1版本的配置和使用简介
下一篇: PHP的包依赖管理工具Composer简介
zzulp
博客等级 码龄19年 464粉丝 176原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值