【Python】日本語のURL表示がおかしいときの対策【URLエンコード】

この記事は約5分で読めます。

日本語を含んだURLをメモ帳などに貼り付けてもわかりますが
日本語の部分が%〇~に変換されてます。
原因はURLエンコード されているからです。
URLエンコード(パーセントエンコーディング) とは何かの解説と
Pythonで日本語表示に直すやり方を紹介します。

URLエンコード(パーセントエンコーディング)

URLでは本当は日本語が使えません。
使えるようにURLエンコード(パーセントエンコーディング)してます。
やたらと%がついてるURLを見たことがあると思います。
それが日本語のURLを URLエンコード したものです。
Windowsの場合ブラウザのアドレスバーに表示されてる
日本語URLをコピーしてメモ帳などに貼り付けると
URLエンコードされたものが貼り付けられます。

パソコンで扱う文字は番号で割り振られています。
文字と番号の対応がいくつかありShift-JISやutf-8などがあります。
番号は16進数表記なのでAからFまでのアルファベットも出てきます。
WindowsのEdgeでやってますがutf-8のようです。
utf-8のコード表を使った場合、例えば日本語の「プロフィール」は
プ=E38397 ロ=E383AD フィ=E38395 ィ=E382A3 ー=E383BC ル=E383AB
これをつなげると E38397E383ADE38395E382A3E383BCE383AB
これで終わりではなく
URLエンコード(パーセントエンコーディング)されてることを表すため
2桁(正確には1バイト)ずつ%で区切られています。
結果 「プロフィール」 のURLエンコードは
%E3%83%97%E3%83%AD%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB/となります。

urllib.parseモジュール

Pythonではこの処理をurllib.parseモジュールでやってくれます。
日本語URLをエンコード(%○○%○○~)したり
デコード(日本語表示に戻す)ができます。
エンコードはurllib.parse.quote
デコードはurllib.parse.unquote

日本語を含んだhttps://kikuichige.com/プロフィール/のようなURLの日本語部分が
エンコードされると
https://kikuichige.com/%E3%83%97%E3%83%AD%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB/となります。
これはプラウザのアドレスバーで
https://kikuichige.com/プロフィール/ と表示されてるのをコピーして
貼り付けたらエンコードされた状態で貼り付けられました。

疑似的に urllib.parse.quote と urllib.parse.enquoteを使ってやってみると

a='https://kikuichige.com/'+urllib.parse.quote('プロフィール/')
print('エンコード')
print(a)
print('デコード')
print(urllib.parse.unquote(a))

結果
エンコード
https://kikuichige.com/%E3%83%97%E3%83%AD%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB/
デコード
https://kikuichige.com/プロフィール/

実行した結果エンコードとさっき張り付けたものは同じになります。
これを urllib.parse.unquote でデコードすると日本語URLになります。
目次へ

urllib.parseモジュール でうまくいかない場合

しかし以下のようなスクレーピングのあとURLを整えようとしたプログラムでは
a_tag.get(‘href’).split(‘&sa=U&’)[0].replace(‘/url?q=’, ”)
以下のような2回エンコードされたものが出力されました。

'https://kikuichige.com/%25E3%2581%258A%25E5%2595%258F%25E3%2581%2584%25E5%2590%2588%25E3%2582%258F%25E3%2581%259B/'

1回エンコードしてできた%の部分が全部%25になっています。
utf-8のコード表で%を見ると25です。
これは文字「%」がURLエンコードされて%25になってます。
半角英数はそのまま。
記号はエンコードされるものとされないものがあります。
(ちなみにアドレス全体を urllib.parse.quote でエンコードすると
https:の:は%3Aにエンコードされてしまいます「.」と「/」と半角英数はそのままです。)

原因は追えてませんが
2回デコードすると日本語URLになるので urllib.parse.unquote を2回かけてます。

 a_tag1=urllib.parse.unquote(urllib.parse.unquote(a_tag.get('href').split('&sa=U&')[0].replace('/url?q=', '')))

ついでにもう少しこの処理を解説します。
a_tag.get(‘href’)だけでurlを抽出すると下のように余計なものがいっぱいついてきます。

/url?q=https://kikuichige.com/%25E3%2583%2597%25E3%2583%25AD%25E3%2583%2595%25E3%2582%25A3%25E3%2583%25BC%25E3%2583%25AB/&sa=U&ved=2ahUKEwi2ypmp46H1AhXZA4gKHeMrDmYQFnoECBAQAg&usg=AOvVaw1kRxxkU9Casr2p3hVHD_Yt'

使えるurlにした処理内容を解説すると

先頭の ‘/url?q=’ を空白で置き換え(replace)
日本語urlが文字化けしないように2回 urllib.parse.unquote でデコード
&sa=U& で分割、要素2個の配列になるので0番目の要素だけ残し
1番目(下の緑太字)は使わない。

[‘https://kikuichige.com/%25E3%2583%2597%25E3%2583%25AD%25E3%2583%2595%25E3%2582%25A3%25E3%2583%25BC%25E3%2583%25AB/’ , ‘&sa=U&ved=2ahUKEwi2ypmp46H1AhXZA4gKHeMrDmYQFnoECBAQAg&usg=AOvVaw1kRxxkU9Casr2p3hVHD_Yt‘]
目次へ

MENTAやってます(ichige)

コメント

タイトルとURLをコピーしました