urlopen()で引数に日本語が含まれているとアクセスできない件【追記あり】
今までファイルを取得してきた中でファイル名に日本語が含まれているものが少なかった。
今回日本語が含まれるファイルがいくつかあったため、その際に取った方法を。
サンプルurl: http://www.nantara.com/ほげほげ.jpg
流れ
①urlに日本語があるか確認する
②日本語があった場合urlopen()でも読める文字列へ変換する
from urllib.parse import quote_plus import unicodedata from urllib.request imprort urlopen def is_japanese_include(url: str) -> bool: """ 引数の文字列に日本語があるか確認する 一字でもあった場合、Trueが返る """ for chara in string: name = unicodedata.name(chara) if "CJK UNIFIED" in name or "HIRAGANA" in name or "KATAKANA" in name: return True return False def edit_string(url: str) -> string: """ urlopen()が読めるように編集する """ tmp_idx = url.rfind("/") url_part = url[:tmp_idx] japanese_part = url[tmp_idx + 1:] url = url_part + "/" + quote_plus(japanese_part, encoding="utf-8") return url def main(): url: str = "http://www.nantara.com/ほげほげ.jpg" is_japanese_include_result: bool = is_japanese_include(url) if is_japanese_include_result: edited_url = edit_string(url) urlopen(edited_url) if __name__ "__main__": main()
ポイントは、日本語の部分を「quote_plus(japanese_part, encoding="utf-8")」で加工しているところ。
参考
【20190621追記】
上記のプログラムを使っても取得できないファイルが出てきた。
サンプルurl: http://www.nantara.com/ほげほげ .jpg
違いは、ファイル名に空白が含まれるか否か。
pythonのurllib.parseのquote_plus()は、url内の空白を「+」へ置き換える。 (だからquote_plusなのか、、)
そして空白を「+」に置き換えられたurlは正しくなく、urlopen()でアクセスはできなかった。
ではこの「+」を何に置き換えれば良いかと思い以下の記事を参考にした。
上記記事内の引用から
TL;DR: use “+” or “%20” in the query-string, use “%20” within the rest of the URL.
空白表すなら「%20」でOK、と解釈したぞ、私は。
つまり、quote_plus()で「+」が発生したら、それを「%20」に置き換える、ということで良いようだ。
以上から、プログラムを修正する。
from urllib.parse import quote_plus import unicodedata from urllib.request import urlopen def is_japanese_include(url: str) -> bool: """ 引数の文字列に日本語があるか確認する 一字でもあった場合、Trueが返る """ for chara in string: name = unicodedata.name(chara) if "CJK UNIFIED" in name or "HIRAGANA" in name or "KATAKANA" in name: return True return False def edit_string(url: str) -> string: """ urlopen()が読めるように編集する """ tmp_idx = url.rfind("/") url_part = url[:tmp_idx] japanese_part = url[tmp_idx + 1:] url = url_part + "/" + quote_plus(japanese_part, encoding="utf-8") if "+" in url: url = url.replace("+", "%20") return url def main(): url: str = "http://www.nantara.com/ほげほげ .jpg" edited_url: str = "" is_japanese_include_result: bool = is_japanese_include(url) if is_japanese_include_result: edited_url = edit_string(url) if edited_url == "": urlopen(url) else: urlopen(edited_url) if __name__ "__main__": main()