一文搞懂 Python 2 字符編碼(一文搞懂傻傻分不清的手機攝像頭CMOS)

      網友投稿 1134 2022-05-30

      我們項目組一值使用Python2.7,雖然我們也知道Python3的諸多好處,也曾經蠢蠢欲動過,但由于各種歷史原因,以及業務的壓力,我們只可能繼續使用Python2.7。更悲哀的是,我們組不是那么international,所以代碼中還是涉及到大量的中文,因此偶爾也會遇到亂碼以及UnicodeError,于是生活在了鄙視鏈的末端。

      因此,本文的目標是解釋清楚 python2.7 中unicode、str的編解碼關系,力求在鄙視鏈中前進一步。

      注意:本文實驗主要基于win7,Python2.7;以及Linux ,Python2.7。除非特殊說明,所有的命令都是在終端中交互式輸入;如果沒有強調平臺,那么就是window上的結果。下面是一些默認的環境信息(其重要性后文會介紹)

      windows

      >>>?import?sys,locale

      >>>?sys.getdefaultencoding()

      'ascii'

      >>>?locale.getdefaultlocale()

      ('zh_CN',?'cp936')

      >>>?sys.stdin.encoding

      'cp936'

      >>>?sys.stdout.encoding

      'cp936'

      >>>?sys.getfilesystemencoding()

      'mbcs'

      注意,上面CP936是GBK的別名,在https://docs.python.org/2/library/codecs.html#standard-encodings?可以查看。

      Linux

      >>>?import?sys,locale

      >>>?sys.getdefaultencoding()

      'ascii'

      >>>?locale.getdefaultlocale()

      ('zh_CN',?'UTF-8')

      >>>?sys.stdin.encoding

      'UTF-8'

      >>>?sys.stdout.encoding

      'UTF-8'

      >>>?sys.getfilesystemencoding()

      'UTF-8'

      從字符編碼說起

      首先來說一說gbk gb2312 unicode utf-8這些術語,這些術語與語言無關。

      計算機的世界只有0和1,因此任何字符(也就是實際的文字符號)也是由01串組成。計算機為了運算方便,都是8個bit組成一個字節(Byte),字符表達的最小單位就是字節,即一個字符占用一個或者多個字節。字符編碼(character encoding)就是字集碼,編碼就是將字符集中的字符映射為一個唯一二進制的過程。

      計算機發源于美國,使用的是英文字母(字符),所有26個字母的大小寫加上數字0到10,加上符號和控制字符,總數也不多,用一個字節(8個bit)就能表示所有的字符,這就是ANSI的“Ascii”編碼(American Standard Code for Information Interchange,美國信息互換標準代碼)。比如,小寫字母‘a’的ascii 碼是01100001,換算成十進制就是97,十六進制就是0x61。計算機中,一般都是用十六進制來描述字符編碼。

      但是當計算機傳到中國的時候,ASCII編碼就行不通了,漢字這么多,一個字節肯定表示不下啊,于是有了GB 2312(中國國家標準簡體中文字符集)。GB2312使用兩個字節來對一個字符進行編碼,其中前面的一個字節(稱之為高字節)從0xA1用到 0xF7,后面一個字節(低字節)從0xA1到0xFE,GB2312能表示幾千個漢字,而且與asill嗎也是兼容的。

      但后來發現,GB2312還是不夠用,于是進行擴展,產生了GBK(即漢字內碼擴展規范), GBK同Gb2312一樣,兩個字節表示一個字符,但區別在于,放寬了對低字節的要求,因此能表示的范圍擴大到了20000多。后來,為了容納少數名族,以及其他漢字國家的文字,出現了GB13080。GB13080是兼容GBK與GB2312的,能容納更多的字符,與GBK與GB2312不同的是,GB18030采用單字節、雙字節和四字節三種方式對字符編碼

      因此,就我們關心的漢字而言,三種編碼方式的表示范圍是:

      GB18030 》 GBK 》 GB2312

      即GBK是GB2312的超集,GB1803又是GBK的超集。后面也會看到,一個漢字可以用GBK表示,但不一定能被GB2312所表示

      當然,世界上還有更多的語言與文字,每種文字都有自己的一套編碼規則,這樣一旦跨國就會出現亂碼,亟待一個全球統一的解決辦法。這個時候ISO(國際標準化組織)出馬了,發明了”Universal Multiple-Octet Coded Character Set”,簡稱 UCS, 俗稱 “unicode”。目標很簡單:廢了所有的地區性編碼方案,重新搞一個包括了地球上所有文化、所有字母和符號 的編碼!

      unicode每種語言中的每個字符設定了統一并且唯一的二進制編碼,以滿足跨語言、跨平臺進行文本轉換、處理的要求。unicode編碼一定以u開頭。

      但是,unicode只是一個編碼規范,是所有字符對應二進制的集合,而不是具體的編碼規則?;蛘哒f,unicode是表現形式,而不是存儲形式,就是說沒用定義每個字符是如何以二進制的形式存儲的。這個就跟GBK這些不一樣,GBK是表里如下,表現形式即存儲形式。

      比如漢字“嚴”的unicode編碼是u4e25,對應的二進制是1001110 00100101,但是當其經過網絡傳輸或者文件存儲時,是沒法知道怎么解析這些二進制的,容易和其他字節混在一起。那么怎么存儲unicode呢,于是出現了UTF(UCS Transfer Format),這個是具體的編碼規則,即UTF的表現形式與存儲格式是一樣的。

      因此,可以說,GBK和UTF-8是同一個層面的東西,跟unicode是另一個層面的東西,unicode飄在空中,如果要落地,需要轉換成utf-8或者GBK。只不過,轉換成Utf-8,大家都能懂,更懂用,而轉換成GBK,只有中國人才看得懂

      UTF也有不同的實現,如UTF-8, UTF-16, 這里以UTF-8為例進行講解(下面一小節引用了阮一峰的文章)。

      unicode與utf-8

      UTF-8最大的一個特點,就是它是一種變長的編碼方式。它可以使用1~4個字節表示一個符號,根據不同的符號而變化字節長度。UTF-8的編碼規則很簡單,只有二條:

      1)對于單字節的符號,字節的第一位設為0,后面7位為這個符號的unicode碼。因此對于英語字母,UTF-8編碼和ASCII碼是相同的。

      2)對于n字節的符號(n>1),第一個字節的前n位都設為1,第n+1位設為0,后面字節的前兩位一律設為10。剩下的沒有提及的二進制位,全部為這個符號的unicode碼。

      下表總結了編碼規則,字母x表示可用編碼的位。

      Unicode符號范圍??????|????????UTF-8編碼方式

      (十六進制)?????????? |????????(二進制)

      ----------------------+---------------------------------------------

      0000?0000-0000?007F?|?0xxxxxxx

      0000?0080-0000?07FF?|?110xxxxx?10xxxxxx

      0000?0800-0000?FFFF?|?1110xxxx?10xxxxxx?10xxxxxx

      0001?0000-0010?FFFF?|?11110xxx?10xxxxxx?10xxxxxx?10xxxxxx

      以漢字“嚴”為例,演示如何實現UTF-8編碼。

      已知“嚴”的unicode是4E25(100111000100101),根據上表,可以發現4E25處在第三行的范圍內(0000 0800-0000 FFFF),因此“嚴”的UTF-8編碼需要三個字節,即格式是“1110xxxx 10xxxxxx 10xxxxxx”。然后,從“嚴”的最后一個二進制位開始,依次從后向前填入格式中的x,多出的位補0。這樣就得到了,“嚴”的UTF-8編碼是“11100100 10111000 10100101”,轉換成十六進制就是E4B8A5。

      當編解碼遇上Python2.x

      下面使用Python語言來驗證上面的理論。在這一章節中,當提到unicode,一般是指unicode type,即Python中的類型;也會提到unicode編碼、unicode函數,請大家注意區別。

      另外,對于編碼,也有兩種意思。第一個是名字,指的是字符的二進制表示,如unicode編碼、gbk編碼。第二個是動詞,指的是從字符到二進制的映射過程。不過后文中,編碼作為動詞,狹義理解為從unicode類型轉換成str類型的過程,解碼則是相反的過程。另外強調的是,unicode類型一定是unicode編碼,而str類型可能是gbk、ascii或者utf-8編碼。

      unicode 與 str 區別

      在python2.7中,有兩種“字符串”類型,分別是str 與 unicode,他們有同一個基類basestring。str是plain string,其實應該稱之為字節串,因為是每一個字節換一個單位長度。而unicode就是unicode string,這才是真正的字符串,一個字符(可能多個字節)算一個單位長度。

      python2.7中,unicode類型需要在文本之間加u表示。

      >>>?us?=?u'嚴'

      >>>?print?type(us),?len(us)

      ?1

      >>>?s?=?'嚴'

      >>>?print?type(s),?len(s)

      ?2

      >>>

      從上可以看到,第一,us、s的類型是不一樣的;其二,同一個漢字,不同的類型其長度也是不一樣的,對于unicode類型的實例,其長度一定是字符的個數,而對于str類型的實例,其長度是字符對應的字節數目。這里強調一下,s(s = ‘嚴’)的長度在不同的環境下是不一樣的!后文會解釋

      __str__ __repr__的區別

      這是python中兩個magic method,很容易讓新手迷糊,因為很多時候,二者的實現是一樣的,但是這兩個函數是用在不同的地方

      _str__, 主要是用于展示,str(obj)或者print obj的時候調用,返回值一定是一個str 對象

      __repr__, 是被repr(obj), 或者在終端直接打obj的時候調用

      >>>?us?=?u'嚴'

      >>>?us

      u'\u4e25'

      >>>?print?us

      可以看到,不使用print返回的是一個更能反映對象本質的結果,即us是一個unicode對象(最前面的u表示,以及unicode編碼是用的u),且“嚴”的unicode編碼確實是4E25。而print調用可us.__str__,等價于print str(us),使得結果對用戶更友好。那么unicode.__str__是怎么轉換成str的呢,答案會在后面揭曉

      unicode str utf-8關系

      前面已經提到,unicode只是編碼規范(只是字符與二進制的映射集合),而utf-8是具體的編碼規則(不僅包含字符與二進制的映射集合,而且映射后的二進制是可以用于存儲和傳輸的),即utf-8負責把unicode轉換成可存儲和傳輸的二進制字符串即str類型,我們稱這個轉換過程為編碼。而從str類型到unicode類型的過程,我們稱之為解碼。

      Python中使用decode()和encode()來進行解碼和編碼,以unicode類型作為中間類型。如下圖所示

      decode    ?encode

      str?--------->?unicode?--------->str

      即str類型調用decode方法轉換成unicode類型,unicode類型調用encode方法轉換成str類型。for example

      >>>?us?=?u'嚴'

      >>>?ss?=?us.encode('utf-8')

      >>>?ss

      '\xe4\xb8\xa5'

      >>>?type(ss)

      >>>?ss.decode('utf-8')?==?us

      True

      從上可以看出encode與decode兩個函數的作用,也可以看出’嚴’的utf8編碼是E4B8A5。

      就是說我們使用unicode.encode將unicode類型轉換成了str類型,在上面也提到unicode.__str__也是將unicode類型轉換成str類型。二者有什么卻比呢

      unicode.encode 與?unicode.__str__的區別

      首先看看文檔

      str.encode([encoding[,?errors]])

      Return?an encoded version of the string.?Default encoding?is?the current default string?encoding.

      object.__str__(self)

      Called by the str()?built-in?function?and?by the print?statement to compute?the?“informal”?string?representation of an object.

      注意:str.encode 這里的str是basestring,是str類型與unicode類型的基類

      可以看到encode方法是有可選的參數:encoding 和 errors,在上面的例子中encoding即為utf-8;而__str__是沒有參數的,我們可以猜想,對于unicode類型,__str__函數一定也是使用了某種encoding來對unicode進行編碼。

      首先不禁要問,如果encode方法沒有帶入參數,是什么樣子的:

      >>>?us.encode()

      Traceback?(most recent call?last):

      File?"",?line?1,?in?

      UnicodeEncodeError:?'ascii'?codec?can't encode character u'\u4e25'?in?position?0:?ordinal?not?in?range(128)

      不難看出,默認使用的就是ascii碼來對unicode就行編碼,為什么是ascii碼,其實就是系統默認編碼(sys.getdefaultencoding的返回值)。ascii碼顯然無法表示漢字,于是拋出了異常。而使用utf-8編碼的時候,由于utf能夠表示這個漢字,所以沒報錯。

      如果直接打印ss(us.encode(‘utf-8’)的返回值)會怎么樣

      >>>?print?ss

      結果略有些奇怪,us.__str__(即直接打印us)的結果不一樣,那么試試encoding = gbk呢?

      >>>?print?us.encode('gbk')

      U got it! 事實上也是如此,python會采用終端默認的編碼(用locale.getdefaultlocale()查看,windows是為gbk)將unicode編碼成str類型。

      在Linux(終端編碼為utf-8),結果如下:

      >>>?us=?u'嚴'

      >>>?print?us.encode('utf-8')

      >>>?print?us.encode('gbk')

      ??

      >>>?print?us

      >>>

      注意上面的亂碼!

      unicode gbk之間的轉換

      在上上小節,介紹了unicode可以通過utf-8編碼(encoding = utf-8),轉換成utf-8表示的str,在上一節也可以看出unicode也可以通過gbk編碼(encoding=gbk),轉換成gbk表示的str。這里有點暈,留作第一個問題,后面解釋

      unicode與utf8之間的相互轉換可以計算得知,但unicode與gbk之間的相互轉換沒有計算公式,就只能靠查表了,就是說有一張映射表,有某一個漢字對應的unicode表示與gbk表示的映射關系

      >>?us?=?u'嚴'

      >>>?us

      u'\u4e25'

      >>>?us.encode('gbk')

      '\xd1\xcf'

      >>>?us.encode('gb2312')

      '\xd1\xcf'

      >>>?us.encode('gb18030')

      '\xd1\xcf'

      >>>?s?=?'嚴'

      >>>?s

      '\xd1\xcf'

      >>>

      從上不難看出,嚴的unicdoe編碼是4e25,GBK編碼是d1cf,因此us通過gbk編碼就是d1cf。同樣也能看到,GB18030,GBK,GB2312是兼容的

      為什么print us.encode(‘utf-8’)打印出“涓”

      ss = us.encode(‘utf-8’), ss是一個str類型,直接打印結果有點奇怪,一個“涓”字,那一個str類型的“涓”是哪些二進制組成的呢

      >>>?s?=?'涓'

      >>>?s

      '\xe4\xb8'

      可以看到,str類型的“涓”,其二進制是E4B8,跟’嚴’的utf8編碼(E4B8A5)相差了一個A5,那么就是因為A5顯示不出來,驗證如下:

      >>>?print?'--%s--'?%?ss

      --涓?-

      因此,只是碰巧顯示了“涓”而已,事實上ss跟“”涓“”毫無關系

      回答第一個問題:str類型到底是什么

      在上上小節,提到了utf-8編碼的str,與gbk編碼的str,感覺有點繞。我們知道,一個漢字‘嚴’,可存儲的編碼格式可以是gbk(’xd1xcf’),也可以是utf-8(’xe4xb8xa5’),那么當我們在終端敲入這個漢字的時候,是哪一種格式呢?取決于終端默認編碼。

      windows上(默認終端編碼為gbk):

      >>>?s?=?'嚴'

      >>>?s

      '\xd1\xcf'

      Linux上(默認終端編碼為utf-8):

      >>>?a?=?'嚴'

      一文搞懂 Python 2 字符編碼(一文搞懂傻傻分不清的手機攝像頭CMOS)

      >>>?a

      '\xe4\xb8\xa5'

      同樣一個漢字,同樣都是Python中的str類型,在不同的編碼格式下,其二進制是不一樣的。因此,其長度也是不一樣的,對于str類型,其長度是對應的字節長度。

      也能看出gbk編碼的字節長度一般小于utf-8,這也是gbk繼續存在的一個原因。

      這里,要強調一下,unicode的二進制形式是與終端的編碼格式無關的!這個也不難理解。

      unicode函數

      str類型到unicode類型的轉換,出了上面提到的str.decode,還有一個unicode函數。兩個函數的簽名為:

      unicode(object[,?encoding[,?errors]])

      Return?the Unicode?string?version of object?using one of the following?modes:

      str.decode([encoding[,?errors]])

      Decodes the string?using the codec registered?for?encoding.?encoding defaults to the default string?encoding.

      二者參數相同,事實上二者是等價的,encoding的默認值也是一樣的,都是sys.getdefaultencoding()的結果。for example:

      >>>?s?=?'嚴'

      >>>?newuse?=?unicode(s)

      Traceback?(most recent call?last):

      File?"",?line?1,?in?

      UnicodeDecodeError:?'ascii'?codec?can't decode byte 0xd1 in position 0: ordinal not in range(128)

      >>> newuse = unicode(s, 'utf-8')

      Traceback (most recent call last):

      File "", line 1, in

      UnicodeDecodeError: 'utf8' codec can't?decode?byte?0xd1?in?position?0:?invalid continuation?byte

      >>>?newuse?=?unicode(s,?'gbk')

      >>>?newuse

      u'\u4e25'

      第一個UnicodeDecodeError,就是因為系統默認的編碼是asill嗎;第二個UnicodeDecodeError,是因為,s(str類型的實例)的編碼取決于終端默認編碼(即windows下的gbk),為了能打印出來,也就必須用gbk編碼來表示這個str,因此只能查詢gbk與unicode的映射表將s轉換成unicode類型。

      為啥調用sys.setdefaultencoding

      在諸多Python代碼中,都會看到這么一段:

      import sys

      reload(sys)

      sys.setdefaultencoding('utf-8')

      不難猜想,setdefaultencoding跟getdefaultencoding是配對的,為啥要將系統的默認編碼設置成utf-8,其實就是解決str到unicode的轉換問題。

      上一小節已經提到過,使用unicode函數將str類型轉換成unicode類型時,要考慮兩個因素:第一,str本身是什么編碼的;第二,如果沒有傳入encoding參數,默認使用sys.getdefaultencoding。encoding參數必須與str本身的編碼對應,否則就是UnicodeDecodeError。

      寫python代碼的程序都知道,我們要在py文件第一行寫上:

      # -*- coding: utf-8 -*-

      這句話的作用在于,告訴編輯器,該文件里面的所有str都采用utf-8編碼,且存儲文件的時候也是使用utf-8格式。

      然后文件中就會使用下面的這種代碼。

      s='中文'

      us=unicode(s)

      使用unicode強制轉換的時候,都不習慣帶參數,為了保證encoding參數必須與str本身的編碼一致,所以使用setdefaultencoding將系統默認編碼設置為utf-8

      亂碼與UnicodeError

      下面介紹幾種常見的亂碼與異常UnicodeError, 大多數亂碼或者異常的原因在前面已經講過了,同時,對于一些亂碼,也試圖給出可行的解決辦法。

      UnicodeError包括UnicodeDecodeError 與UnicodeEncodeError ,前者是decode也就是str轉unicode的時候出了異常,后者則是encode也就是unicode轉str的時候出了異常。

      對于一個str,直接打印

      例子就是上面反復提到的例子

      >>>?ss?=?us.encode('utf-8')

      >>>?print?ss

      如果一個str類型來自網絡或者文件讀取,最好先按照對端encode的方式先decode成unicode,然后再輸出(輸出的時候會自動轉換成期望終端支持的編碼格式的str)

      編碼范圍無法包括的漢字

      直接上例子

      >>>?newus?=?u'囍'

      >>>?newus

      u'\u56cd'

      >>>?newus.encode('gbk')

      '\x87\xd6'

      >>>?newus.encode('gb2312')

      Traceback?(most recent call?last):

      File?"",?line?1,?in?

      UnicodeEncodeError:?'gb2312'?codec?can't encode character u'\u56cd'?in?position?0:?illegal multibyte?sequence

      >>>

      可以看到,‘囍’字可以被gbk編碼,但是不能被gb2312編碼。

      str轉unicode的時候

      在上面講unicode函數的時候已經舉過例子,會爆出UnicodeDecodeError 異常。

      這個錯誤比較的原因,更多來自str到unicode的默認轉換,比如一個str與一個unicode相加的時候:

      >>>?a?=?'嚴'

      >>>?b?=?u'嚴'

      >>>?c?=?a?+?b

      Traceback?(most recent call?last):

      File?"",?line?1,?in?

      UnicodeDecodeError:?'ascii'?codec?can't?decode?byte?0xd1?in?position?0:?ordinal?not?in?range(128)

      unicode 與 str相加,str會轉換為unicode,使用默認的unicode(strobj, encoding = sys.getdefaultencoding())

      看起來向unicode編碼的字符串

      某些情況下,我們打印出一個str類型,看到結果是’\u4e25’, 或者’u4e25’,對于這個字符串,是不是很眼熟,不錯, ‘嚴‘的unicode編碼就是u’u4e25’。仔細一看,只是在引號前面多了一個u(表示是一個unicode類型)。那么當我們看到一個’u4e25’的時候,怎么知道對應的漢字是什么?對于已知的這種格式的str,自然可以手動加一個u,然后在終端輸出,但是如果是一個變量,需要自動轉換成unicode呢,這個時候就可以使用python-specific-encodings中的unicode_escape

      >>>?s?=?'\u4e25'

      >>>?s

      '\\u4e25'

      >>>?us?=?s.decode('unicode_escape')

      >>>?us

      u'\u4e25'

      十六進制格式的字符串

      有時候,也會看到類似這樣的str,’\xd1\xcf’, 看起來也很熟悉,跟漢字“嚴”的gbk編碼’xd1xcf’很像,區別在于前者多了一個‘’, 這樣就無法解釋成一個十六進制了。解決辦法是python-specific-encodings中的string_escape

      >>>?s='\\xd1\\xcf'

      >>>?s

      '\\xd1\\xcf'

      >>>?print?s

      \xd1\xcf

      >>>?news?=?s.decode('string_escape')

      >>>?news

      '\xd1\xcf'

      >>>?print?news

      給讀者的一個問題

      在這里留下一個問題:

      u'嚴' == '嚴'

      返回值是True 還是 False呢?當然這里故意省去了上下文環境,不過明確的說,在不同的編碼環境下,答案是不一樣的,原因都在上文中!

      總結與建議

      不管怎么樣解釋,python2.x中的字符編碼還是一件讓人頭疼的事情,即使搞懂了,之后遇到了也可能忘記。對于這個問題,諸多建議如下:

      第一:使用python3,就不用再糾結str于unicode了;但是這個很難開發者說了算;

      第二:不要使用中文,注釋什么的都用英文;理想很豐滿,現實很難,只是導致大量的拼音;

      第三:對于中文字符串,不要用str表示,而是用unicode表示;現實中也不好實施,大家都不愿意多寫一個u

      第四:只在傳輸,或者持久化的時候對unicode進行encode,相反的過程時decode

      第五:對于網絡接口,約定好編解碼格式,強烈建議使用utf-8

      第六:看到UnicodeXXXError不要慌,如果XXX是Encode,那么一定是unicode轉str的時候出了問題;如果是Decode,一定是str轉unicode的時候出了問題。

      參考

      python codecs

      python-specific-encodings

      字符編碼筆記:ASCII,Unicode 和 UTF-8

      玩轉Python讓人討厭的編碼問題

      Python

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:MSSQL之二十一 存儲過程案例
      下一篇:如何聽起來像數據科學家(什么叫數據科學家)
      相關文章
      亚洲精品视频免费观看| 久久亚洲精品高潮综合色a片| 在线91精品亚洲网站精品成人| 国产成人精品日本亚洲直接 | 亚洲永久中文字幕在线| 亚洲国产综合专区在线电影| 久久精品国产亚洲AV网站| 国产AV无码专区亚洲精品| 亚洲精品无码永久中文字幕| 亚洲日韩国产精品第一页一区| 亚洲熟妇中文字幕五十中出| 亚洲色大成网站www永久一区| 亚洲日韩乱码中文无码蜜桃臀网站| 亚洲中文字幕无码日韩| 亚洲性猛交XXXX| 亚洲AV无码一区二区乱子伦| 亚洲av成人无码久久精品| 亚洲日韩图片专区第1页| 91亚洲va在线天线va天堂va国产| 久久久久亚洲AV无码麻豆| 久久夜色精品国产噜噜噜亚洲AV| 亚洲成a人片7777| 久久精品国产亚洲AV久| 亚洲综合小说另类图片动图| 亚洲日本天堂在线| 亚洲AV色无码乱码在线观看| 国产亚洲视频在线| 精品国产香蕉伊思人在线在线亚洲一区二区| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 亚洲三级视频在线观看| 77777午夜亚洲| 亚洲乱妇老熟女爽到高潮的片| 亚洲色大情网站www| 偷自拍亚洲视频在线观看99| 国产国拍亚洲精品福利| 国产精品久久久亚洲| 亚洲视频在线观看网站| 亚洲精品亚洲人成在线| 国产天堂亚洲精品| 国产亚洲色视频在线| 亚洲AV无码久久精品狠狠爱浪潮|