天天看點

原來可以這樣中文轉碼

大家做爬蟲時,是不是也遇到過url是中文,然後在顯示時轉碼了的情況,一長串字元,根本就不知道是什麼,要驗證的時候很不友善,這裡分享一下我的處理方法。

一、嘗試

一長串字元,首先想到用線上unicode轉中文,結果還是不知道是什麼.

原内容:

%5B9500%5D%5B552e%5D%5B6307%5D%5B6807%5D%5B5b8c%5D%5B6210%5D%5B7387%5D111
%5B8d39%5D%5B7528%5D%5B989d%5D%5B5ea6%5D%5B67e5%5D%5B8be2%5D
           

轉後:

[9500][552e][6307][6807][5b8c][6210][7387]111
[8d39][7528][989d][5ea6][67e5][8be2]
           

心想這是什麼東西?

難道就這樣失敗了?

仔細看看内容,四個字,四個字的,是不是有點像unicode?可是中括号是什麼鬼?

試着拿一個數試試,

\u9500

.

原來可以這樣中文轉碼
原來可以這樣中文轉碼

果然,不是巧合,真的就是unicode, 可是這麼多括号,手動解決是不可能的。

二、怎麼才能去除括号并且換上

\u

呢?

當然首選是pyhton, 上代碼:

# coding=utf-8
from urllib import parse
import re


def _change(matched):
    if matched.group(0) == "[":
        return '\\u'
    else:
        return ''


def url_de(x):
    '''對URL進行解碼'''
    replaceStr = re.sub(
        r'([\[|\]])', _change, parse.unquote(x))
    return replaceStr



x = '''
%5B9500%5D%5B552e%5D%5B6307%5D%5B6807%5D%5B5b8c%5D%5B6210%5D%5B7387%5D111
%5B8d39%5D%5B7528%5D%5B989d%5D%5B5ea6%5D%5B67e5%5D%5B8be2%5D
'''

print(url_de(x))
           

首先,我們引入要用的包,這裡主要是兩個包,parse用來做第一遍轉碼,轉成帶括号的形式。然後使用re.sub對括号進行替換和消除。

輸出:

原來可以這樣中文轉碼

其實應該有方法再轉一次輸出中文的,可是一時半會沒找到方法。隻能用笨辦法了,複制輸出的内容到線上unicode轉中文。

原來可以這樣中文轉碼

成功了,原來是這樣。

原來可以這樣中文轉碼

三、 轉機

就在我打算先這麼樣的時候,一個朋友給出了一個方法。

謝謝 @程式員喜歡貓 的幫助,使用json 可以順利的解析出中文,不用反複使用 線上unicode轉中文 。

新的代碼也放到下面:

# coding=utf-8
from urllib import parse
import re
import json


def _change(matched):
    if matched.group(0) == "[":
        return '\\u'
    else:
        return ''

# 原來方法加上json.loads


def url_de(x):
    '''對URL進行解碼'''
    replaceStr = re.sub(
        r'([\[|\]])', _change, parse.unquote(x))
    return json.loads(f'"{replaceStr}"')

# @程式員喜歡貓 提供的方法


def func(string):
    string = parse.unquote(string)
    string = string.replace('[', '\\u').replace(']', '')
    return json.loads(f'"{string}"')


x = 'http://www1.site.com:8888/WebReport/ReportServer?formlet=/test/[7efc][5408][5206][6790]/zonghexinxi_erji_yiyao_tuiguangbu--%5B9500%5D%5B552e%5D%5B6307%5D%5B6807%5D%5B5b8c%5D%5B6210%5D%5B7387%5D111.frm'
print('方法一:')
print(url_de(x))
print('方法二:')
print(func(x))
           

四、結果:

原來可以這樣中文轉碼

很明顯中文已經解析出來了,不用再去 線上unicode轉中文 了, 完美,再次感謝 @程式員喜歡貓

五、再進一步

果然是方法總比問題多,經過 @程式員喜歡貓 的提醒,我想應該方法不止這些,又上網搜尋了下,果然,也有小夥伴遇到這個問題,具體可見 https://www.zhihu.com/question/26921730

于是現改進方法:

def url_de(x):
    '''對URL進行解碼'''
    replaceStr = re.sub(
        r'([\[|\]])', _change, parse.unquote(x))
    return replaceStr.encode('latin-1').decode('unicode_escape')
           

六、效果:

原來可以這樣中文轉碼

注意:

這裡需要注意的是, 如mailto1587 說的:

先檢查text是什麼類型如果

type(text) is bytes

,那麼

text.decode('unicode_escape')

如果

type(text) is str

,那麼

text.encode('latin-1').decode('unicode_escape')

用這種方法可以不用引入 json , 了解起來更自然點。

七、後記:

這次的問題其實還是比較簡單的,但是我們在做爬蟲的過程中,這種問題層出不窮,怎麼以簡便快捷的方式處理問題就很重要了,但是在處理好問題後,我們還可以進一步研究,怎麼才能做的更好,進步就再這一點點。歡迎大家關注我的公衆号 Python與跨境電商 一起讨論。