爬虫从网站上爬取的内容在读写操作时经常会报以下错误:
UnicodeEncodeError: 'gbk' codec can't encode character '\u200b' in position 7: illegal multibyte sequence
所以需要我们对数据Unicode进行清洗,排除文章内异常的Unicode符号。
清洗思路
我的思路是用正则表达式来匹配常用字,不在范围内的Unicode编码则去除。
.compile(u"[^常用字范围]+")匹配到非范围内字符后,
.sub()方法将特殊字符替换成空
def illegal_char(s):
s = re \
.compile( \
u"[^"
u"\u4e00-\u9fa5"
u"\u0041-\u005A"
u"\u0061-\u007A"
u"\u0030-\u0039"
u"\u3002\uFF1F\uFF01\uFF0C\u3001\uFF1B\uFF1A\u300C\u300D\u300E\u300F\u2018\u2019\u201C\u201D\uFF08\uFF09\u3014\u3015\u3010\u3011\u2014\u2026\u2013\uFF0E\u300A\u300B\u3008\u3009"
u"\!\@\#\$\%\^\&\*\(\)\-\=\[\]\{\}\\\|\;\'\:\"\,\.\/\<\>\?\/\*\+"
u"]+") \
.sub('', s)
return s
Unicode范围
常用范围
名称 | 范围 |
---|---|
中文 | \u4e00-\u9fa5 |
日文平假名 | \u3040-\u309f |
日文片假名 | \u30a0-\u30ff |
韩文 | \uac00-\ud7ff |
英文字母 | \u0041-\u005A\u0061\u007A |
数字 | \u0030-\u0039 |
英文标点 | !@#$%^&*()-=[]{}\;':",./<>?/*+ |
中文标点 | 使用下面的中文标点挨个匹配 |
注:网上有种方法写的中文标点匹配是 \u3000-\u303f\ufb00-\ufffd,但\u301c\ufffd在GBK中没有对应字符,仍然会报错,建议将中文标点挨个匹配
中文标点对应
名称 | Unicode | 符号 |
---|---|---|
句号 | \u3002 | 。 |
问号 | \uFF1F | ? |
叹号 | \uFF01 | ! |
逗号 | \uFF0C | , |
顿号 | \u3001 | 、 |
分号 | \uFF1B | ; |
冒号 | \uFF1A | : |
引号 | \u300C | 「 |
\u300D | 」 | |
\u300E | 『 | |
\u300F | 』 | |
\u2018 | ‘ | |
\u2019 | ’ | |
\u201C | “ | |
\u201D | ” | |
括号 | \uFF08 | ( |
\uFF09 | ) | |
\u3014 | 〔 | |
\u3015 | 〕 | |
\u3010 | 【 | |
\u3011 | 】 | |
破折号 | \u2014 | —— |
省略号 | \u2026 | …… |
连接号 | \u2013 | – |
间隔号 | \uFF0E | . |
书名号 | \u300A | 《 |
\u300B | 》 | |
\u3008 | 〈 | |
\u3009 | 〉 |
非英文语系字符范围
范围 | 编码 | 说明 |
---|---|---|
2E80~33FFh | 中日韩符号区 | 收容康熙字典部首、中日韩辅助部首、注音符号、日本假名、韩文音符,中日韩的符号、标点、带圈或带括符文数字、月份,以及日本的假名组合、单位、年号、月份、日期、时间等。 |
3400~4DFFh | 中日韩认同文字扩充A区 | 中日韩认同表意文字扩充A区,总计收容6,582个中日韩汉字。 |
4E00~9FFFh | 中日韩认同表意文字区 | 中日韩认同表意文字区,总计收容20,902个中日韩汉字。 |
A000~A4FFh | 彝族文字区 | 收容中国南方彝族文字和字根 |
AC00~D7FFh | 韩文拼音组合字区 | 收容以韩文音符拼成的文字 |
F900~FAFFh | 中日韩兼容表意文字区 | 总计收容302个中日韩汉字 |
FB00~FFFDh | 文字表现形式区 | 收容组合拉丁文字、希伯来文、阿拉伯文、中日韩直式标点、小符号、半角符号、全角符号等。 |
使用样例
import re
str1 = '33?3-3aa.,a中*文,a——a。a_+】!@@#$%^&*()(_++-[]{}\|";/<>.'
print(re.compile(u"[^\u4e00-\u9fa5]+").sub('', str1)) # 中文
print(re.compile(u"[^\u0041-\u005A|\u0061\u007A]+").sub('', str1)) # 英文
print(re.compile(u"[^\u0030-\u0039]+").sub('', str1)) # 数字
print(re.compile(u"[^\u3002|\uFF1F|\uFF01|\uFF0C|\u3001|\uFF1B|\uFF1A|\u300C|\u300D|\u300E|\u300F|\u2018|\u2019|\u201C|\u201D|\uFF08|\uFF09|\u3014|\u3015|\u3010|\u3011|\u2014|\u2026|\u2013|\uFF0E|\u300A|\u300B|\u3008|\u3009]+").sub('', str1)) # 中文标点
print(re.compile(u"[^\!\@\#\$\%\^\&\*\(\)\-\=\[\]\{\}\\\|\;\'\:\"\,\.\/\<\>\?\/\*\+]+").sub('',str1)) # 英文标点
输出结果
中文
aaaaaa
3333
,。】
,——。】
?-.*,+!@@#$%^&*()(++-[]{}\|";/<>.