大家做爬蟲時,是不是也遇到過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
呢?
\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與跨境電商 一起讨論。