python2 编码问题小解决;sys;unicode-escape

今天作者想要分享的是自己在爬取网站过程中一些简单的编码问题,当然说是简单问题作者也是搜索了很久,今天分享下来方便以后自己在遇到这类问题更好的解决。
环境:python2
目标网站种的内容如下图:
这里写图片描述
从爬取出来的代码来看这些字段并没有乱码,但是啊在作者进行提取的过程种发现提取到的内容并不是正常的内容,作者这里简单分享一下自己。后续会持续分享一些编码的问题。

信息的提取:

car_res = etree.HTML(car_res.content)
all_car = car_res.xpath('//div[@name="SearchKey"]/@id')
for each_car in all_car[1:]:
    print each_car

但是获取的结果并不如意:

粤BF7983_13300768817
粤BGD695_13300768868
粤BV9402_13725023706
粤BEU601_13816018047
粤B35CU5_13816029721
粤B8FP29_13816072371
粤B89DH5_13820034541
粤BDA851_13821008623
粤BF7983_13300768817

从结果来看本应该是车牌号而此时的获取却乱码了,作者不仅怀疑为什么,就去看网页的源码看看网页种的charset编码格式是什么?
这里写图片描述
从截图来看,网页中的编码是utf-8 那么便考虑当自己采集的时候可以先获取字节然后通过utf-8 进行解码岂不是美滋滋,这样问题应该就会解决了。
这里写图片描述
当然我们知道在python2.7中.text表示的是字节,.content 是字符,所以笔者在工作中的代码是:

car_res = etree.HTML(car_res.text.decode('utf-8'))
all_car = car_res.xpath('//div[@name="SearchKey"]/@id')
car_infos = []
for each_car in all_car[1:]:
    print each_car

然而不幸的是发现结果仍然是:

粤BF7983_13300768817
粤BGD695_13300768868
粤BV9402_13725023706
粤BEU601_13816018047
粤B35CU5_13816029721
粤B8FP29_13816072371
粤B89DH5_13820034541

真滴是尴尬……………..便想到了重新进行系统编码的设置,通过导入sys模块

import sys

reload(sys)  // 为什么添加你可参考链接:http://www.360doc.com/content/15/0105/15/9934052_438371998.shtml
sys.setdefaultencoding("utf-8")

关于为什么要用这个模块,首先作者理解的解释一下:Python 默认脚本文件都是 UTF-8 编码的,当文件中有非 UTF-8 编码范围内的字符的时候就要使用”编码指示”来修正. 关于 sys.defaultencoding,这个在解码没有明确指明解码方式的时候使用。
具体的理解可以这样理解:

res = '这是代码'
print (res.encode('gb2312'))  // 然而结果却提示的错误是

这里写图片描述
这句代码将 res 重新编码为 gb2312的格式,即进行 unicode -> str 的转换。因为 res本身就是 str 类型的,因此
Python 会自动的先将 res 解码为 unicode ,然后再编码成 gb2312。因为解码是python自动进行的,而我们有没有指明解码方式,python 就会使用 sys.defaultencoding 指明的方式来解码。很多情况下 sys.defaultencoding 是
ANSCII,显然的我们的res不是这个类型。拿上面的情况来说,我的 sys.defaultencoding 是 anscii,而 res 的编码方式和文件的编码方式一致,是 utf8 的,所以出错了。所以这个时候具体的解决办法是:

# coding=utf-8
res = '这是代码'
print (res.decode('utf-8').encode('gb2312'))

当然了也可以通过更改 sys.defaultencoding 为文件的编码方式

#coding=utf-8

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

res = '这是代码'
print (res.encode('gb2312')) // 结果就是正确的当然这只是举例,gb2312也可以是任何的编码格式。

好了言归正传,在本文中笔者便想到这种方法,然而却依然是错误的编码格式,这时候笔者采用了两种解决的方式:
第一种:

car_res = res.get(url=car_url, headers=car_headers)
car_res.encoding = "utf-8"  // 对获取到的内容通过utf-8进行整体的编码
car_res = etree.HTML(car_res.text)
all_car = car_res.xpath('//div[@name="SearchKey"]/@id')
car_infos = []
for each_car in all_car[1:]:
    print each_car

结果如下:

粤BF7983_13300768817
粤BGD695_13300768868
粤BV9402_13725023706
粤BEU601_13816018047
粤B35CU5_13816029721
粤B8FP29_13816072371
粤B89DH5_13820034541
粤BDA851_13821008623

显然结果是自己想要的。
第二种方法:

car_res = etree.HTML(unicode(car_res.content, 'utf-8', errors='replace'))  
all_car = car_res.xpath('//div[@name="SearchKey"]/@id')
car_infos = []
for each_car in all_car[1:]:
    print each_car

结果同样是自己想要的:

粤BF7983_13300768817
粤BGD695_13300768868
粤BV9402_13725023706
粤BEU601_13816018047
粤B35CU5_13816029721
粤B8FP29_13816072371
粤B89DH5_13820034541

unicode(car_res.content, 'utf-8', errors='replace') unicode 这个方法可以点击去看其返回值

def __init__(self, string=u'', encoding=None, errors='strict'): # known special case of unicode.__init__
    """
    unicode(object='') -> unicode object
    unicode(string[, encoding[, errors]]) -> unicode object

    Create a new Unicode object from the given encoded string.
    encoding defaults to the current default string encoding.
    errors can be 'strict', 'replace' or 'ignore' and defaults to 'strict'.
    # (copied from class doc)
    """
    pass

好了,今天的分享到这里就结束了。后续如果遇到编码问题会持续分享。
还有一个问题是作者在解析字段的时候遇到的

dd = "苏MJ6368"
dd = dd.replace('&#x', '\\u').replace(';', '').decode('unicode-escape')
print dd  参考:https://www.cnblogs.com/leomei91/p/7685797.html
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页