Python3爬虫之中文乱码问题分析与解决方法

前言

分析

解决方法


前言:

今天简单爬取一个网页的源代码时,发现出现了乱码
python代码:python

import requests

req = requests.get("http://www.ccit.js.cn")
req_text = req.text
print(req_text)

部分截图:
在这里插入图片描述web


分析:出现这样的状况是什么缘由呢?

(1)咱们先来测试一下python3的默认编码是什么svg

import sys

print('目前系统的编码为:',sys.getdefaultencoding())
name1="惊鸿一面"
name2=name1.encode("utf-8")#str经过(encode)转为bytes
print("name1的类型:",type(name1))
print("name2的类型",type(name2))
print(name2)

运行结果:
在这里插入图片描述
(2)知识点:测试

  • python3默认编码为utf-8(unicode的一个子集,也是属于unicode,这也就是为何有人说python3的默认编码是unicode,其实是和utf-8是同样的)
  • 字符串用str表示,编码后的字符串用二进制bytes表示
  • 字符串经过编码转换为字节码,字节码经过解码转换为字符串
    str经过(encode)转为bytes,bytes经过(decode)转为str

(3)缘由总结:
Python3的默认编码是utf-8,全部的数据他都会以utf-8进行编码(encode)。所以,Python3将目标网站的源码爬取以后进行utf-8编码,但咱们所爬取的目标网站是GB2312编码,与Python3的默认编码不一样,于是形成乱码
解决方案:
使用通用的编码格式网站

(4)注:ui

  • str类型的对象都是unicode,所以对于str类型的对象只有encode()方法,没有decode()方法(若是运行,会报错)
    缘由是:只有bytes(二进制)的值才能decode,你字符串是吗??!!
  • 避免出现乱码的准则:
    遵循编码使用哪一种格式,解码就使用哪一种格式。
  • 出现相似UnicodeEncodeError: 'gb2312' codec can't encode character '\xb3' in position 293: illegal multibyte sequence的缘由是,你须要解码的文件中有些中文字符没法进行解码(有些中文字符是不在GB2312范围内的)
    此时,咱们能够使用它GBK或者它的父集GB18030

(5)咱们以几种常见的编码格式进行encode测试编码

import requests
req= requests.get("http://www.ccit.js.cn")
req_text1=req.text.encode("utf-8")
req_text2=req.text.encode("GB2312")
req_text3=req.text.encode("GB18030")
print(req_text1)#成功编码成bytes
print(req_text2)#UnicodeEncodeError: 'gb2312' codec can't encode character '\xb3' in position 293: illegal multibyte sequence
print(req_text3)#成功编码成bytes

(6)接着上面又作了decode测试,遵行编码使用准则,可是仍是乱码!!spa

import requests

req= requests.get("http://www.ccit.js.cn")

req_text1=req.text.encode("utf-8").decode("utf-8")
req_text2=req.text.encode("utf-8").decode("GB2312")
req_text3=req.text.encode("utf-8").decode("GB18030")

req_text4=req.text.encode("GB18030").decode("utf-8")
req_text5=req.text.encode("GB18030").decode("GB2312")
req_text6=req.text.encode("GB18030").decode("GB18030")

print(req_text1)#成功可是乱码
print(req_text2)#UnicodeDecodeError: 'gb2312' codec can't decode byte 0xc3 in position 297: illegal multibyte sequence
print(req_text3)#成功可是乱码
print(req_text4)#UnicodeDecodeError: 'utf-8' codec can't decode byte 0x81 in position 293: invalid start byte
print(req_text5)#UnicodeDecodeError: 'gb2312' codec can't decode byte 0x81 in position 293: illegal multibyte sequence
print(req_text6)#成功可是乱码

解决方法:

那到底怎样才能解决呢???请看以下代码:code

import requests
req= requests.get("http://www.ccit.js.cn")
req_text=req.text.encode("latin1").decode("GBK")
print(req_text)

这里进行encode时使用了latin1。xml

  • Latin1是ISO-8859-1的别名,有些环境下写做Latin-1。ISO-8859-1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间彻底和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。
  • 由于ISO-8859-1编码范围使用了单字节内的全部空间,在支持ISO-8859-1的系统中传输和存储其余任何编码的字节流(bytes)都不会被抛弃。换言之,把其余任何编码的字节流看成ISO-8859-1编码看待都没有问题。