在网页抓取时,经常遇到网页编码问题,以下是自己总结的干货
一、几篇文章
字符串编码与Python 3编码:http://blog.csdn.net/wangtaoking1/article/details/51326754
python3 和 python2 的编码与解码差别很大吗?:https://www.v2ex.com/t/343040
Python 3的bytes/str之别 codecs模块:http://blog.csdn.net/iamaiearner/article/details/9138865
自学Python八 爬虫大坑之网页乱码:http://www.cnblogs.com/jixin/p/5141701.html
二、个人总结
Begin with Python 3, all string is unicode object.-->也就是说所有str字符串已经是Unicode(utf8)了,不用再decode
python3中就是两个东西:bytes与str(即二进制与字符串(其实可以理解就是utf8、unicode))
最终转成UTF8输出是毋庸置疑的。
抓的如果是中文页面的话,用GB18030来decode是比较正统的方法,gb2312是一个误区,其实我们的页面中使用的字符编码已经早就超出2312的那些了。
明明是中文页面抓回来却没法用18030来decode的话,一般是因为页面中混杂了非法字符的原因,可以用ignore忽略掉非法字符。
三、自己遇到的坑
有些网页抓取并解码后,英文正确显示,中文还是出现乱码,怎么解码都弄不好,以下解决方案完美解决了我的问题。
unicode中的‘\xa0’字符在转换成gbk编码时会出现问题,gbk无法转换'\xa0'字符。所以,在转换的时候必需进行一些前置动作:
sting.replace('\xa0', ' ') #将'\xa0'替换成' '空格。
这个坑解决问题的示例:
import urllib.request
url = "http://www.ebay.com/sch/TShirts-/15687/i.html?Style=Basic%2520Tee&_dcat=15687&Color=Black&_pgn=1"
req = urllib.request.Request(url)
html_open = urllib.request.urlopen(req)
html_data = html_open.read()
html = str(html_data.decode("utf8")) #先read再decode
html = html.replace("\xa0"," ")
html = html.replace("\xa9"," ")
html.encode("utf8")
file_name = "f:/test/1.txt"
file_open = open(file_name, "a") #将网页源码写入1.txt中
file_open.write(html)
file_open.close()
这个方法在实际问题中解决了问题:
#本代码解决解码后乱码或者其他部分英文都正确但网页中文仍然乱码的问题
import re
import urllib.request
def getPage(url):
request = urllib.request.Request(url)
response = urllib.request.urlopen(request)
data = response.read()
return data.decode("utf8") #这里建议网页抓取下来都进行decode原网页的编码格式,utf8也不例外。这里的实例网页编码格式为utf8
urls = open("f:/4.txt") #从4.txt中提取urls,一共两个url,都为utf8编码方式
for url in urls:
url = url.replace("\n","")
result=getPage(url)
result = str(result)
result = result.replace("\xa0"," ") #这里是关键中重点,就是因为'\xa0'是个空格符的问题造成中文出现乱码
result.encode("gbk") #上行代码将空格符去掉后,再encode成支持中文的编码就可以看到中文了,当然这行代码可以省略,因为默认是可以显示的
rule = re.compile("http://(.*?)/") #以下代码:将源码写入文件中,这里把文件名http等前后缀去掉
new_url = re.findall(rule, url)
save_name = "f:/savepages/" + new_url[0] + ".txt"
file_open = open(save_name, "a")
file_open.write(result)
file_open.close()