Lors de l'accès à une URL contenant du japonais (URL japonais) avec python3 avec urllib, elle sera encodée arbitrairement avec html et une erreur se produira, alors notez la solution de contournement

Contenu

Contexte

Contenu trébuché

response = urllib.request.urlopen(url)

c'est normal. Accédez simplement à l'url et faites l'objet. ___ Cependant, une tragédie s'est produite parce que cette URL contenait du japonais.

url = 'http: //image.search.yahoo.co.jp/search? p = Evangelion' C'est comme ça.

Vous serez entraîné dans les ténèbres de python avec hâte. *** Ajout des détails d'erreur. *** ***

Traceback (most recent call last):
・ ・ ・
    response = urllib.request.urlopen(link)
  File "/Users/mix/.pyenv/versions/3.5.0/lib/python3.5/urllib/request.py", line 162, in urlopen
    return opener.open(url, data, timeout)
  File "/Users/mix/.pyenv/versions/3.5.0/lib/python3.5/urllib/request.py", line 465, in open
    response = self._open(req, data)
  File "/Users/mix/.pyenv/versions/3.5.0/lib/python3.5/urllib/request.py", line 483, in _open
    '_open', req)
  File "/Users/mix/.pyenv/versions/3.5.0/lib/python3.5/urllib/request.py", line 443, in _call_chain
    result = func(*args)
  File "/Users/mix/.pyenv/versions/3.5.0/lib/python3.5/urllib/request.py", line 1268, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "/Users/mix/.pyenv/versions/3.5.0/lib/python3.5/urllib/request.py", line 1240, in do_open
    h.request(req.get_method(), req.selector, req.data, headers)
  File "/Users/mix/.pyenv/versions/3.5.0/lib/python3.5/http/client.py", line 1083, in request
    self._send_request(method, url, body, headers)
  File "/Users/mix/.pyenv/versions/3.5.0/lib/python3.5/http/client.py", line 1118, in _send_request
    self.putrequest(method, url, **skips)
  File "/Users/mix/.pyenv/versions/3.5.0/lib/python3.5/http/client.py", line 960, in putrequest
    self._output(request.encode('ascii'))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 14-21: ordinal not in range(128)

Pour autant que je vois l'erreur, ~~ urllib essaie juste de se convertir en ASCII, non? ?? ?? ~~ PS: http essayait de convertir l'URL en ascii! !!

Solution de contournement Où! J'ai cherché La partie japonaise doit être analysée ~~. ~~ Post-scriptum: vous devez effectuer un encodage d'URL (encodage en pourcentage).

urllib.parse.quote_plus('Evangelion', encoding='utf-8')

C'est comme ça? Il y a un problème avec cela. .. ..

url = 'http://image.search.yahoo.co.jp/search?p=' + urllib.parse.quote_plus('Evangelion', encoding='utf-8')

Si vous le faites honnêtement, ce sera comme ça. .. .. Vous pouvez également spécifier une chaîne de caractères à exclure lorsque vous la recherchez! Il semble que vous devriez le passer comme deuxième argument.

urllib.parse.quote_plus(url, "/:?=&")

C'est comme ça? Il peut y avoir des omissions dans les caractères qui ne sont pas couverts. .. .. Cela a fonctionné avec cela, mais j'étais un peu inquiet, il existe donc une autre méthode.

Au contraire (?) Je devrais remplacer tous les japonais! J'ai essayé de faire ça.

Ce que j'ai fait

C'est confu! Cependant, avec cette méthode, les mots qui correspondent à l'expression régulière Vous pouvez le remplacer "le passer à une fonction et utiliser le résultat".

Je voulais faire quelque chose à ce sujet, mais je ne pouvais pas penser que c'était une tête raide. .. .. Je ne sais pas grand-chose sur python, donc ce n'est pas bon à première vue. .. .. Il semble que lambda n'ait pas non plus d'effets secondaires. S'il vous plaît laissez-moi savoir s'il y a autre chose. Est-ce un itérateur?

regex = r'[Ah-Gaa-熙]'
matchedList = re.findall(regex,url)
for m in matchedList:
   url = url.replace(m, urllib.parse.quote_plus(m, encoding="utf-8"))

Quand il s'agit de tous les japonais De nombreux articles disent [A-n], En regardant la table des codes de caractères, c'est vraiment "ga"!

alors! !! Même si vous exposez du code sale avec python qui n'est pas du tout familier Je l'ai écrit parce que je veux partager cette dernière surprise.

Postscript: méthode de spécification correcte de l'expression régulière

@ KeisukeKudo-san m'a donné quelques mesures d'amélioration, je vais donc les présenter ici aussi! Strictement parlant, ma notation est fuyante, donc si vous voulez l'utiliser, veuillez utiliser ce qui suit.

regex = r'[Ah-Gaa-熙]'
#Modifié ce qui précède comme suit
regex = r'[^\x00-\x7F]'

Que diriez-vous d'essayer [\x00-\x7F] Il s'agit d'une expression régulière qui correspond au caractère ascii. En utilisant la forme négative ci-dessus, vous pouvez obtenir les caractères qui correspondent au japonais. http://rubular.com/r/2dnoBUlKe9

Postscript: la méthode la plus correcte pour cette réponse

@ komeda-shinji m'a donné quelques mesures d'amélioration, je vais donc les présenter ici aussi! Penser spécifiquement à ce que vous voulez faire, quand il y a des caractères dans la requête URL qui ne peuvent pas être convertis en ascii Ce qui suit est préférable car cela signifie que l'URL est encodée en premier.

Il est décomposé par le composant d'URL et seule la requête est encodée et reconstruite en URL.

from urllib.parse import urlparse
import urllib.request

url = 'http://image.search.yahoo.co.jp/search?p=Evangelion'
p = urlparse(url)
query = urllib.parse.quote_plus(p.query, safe='=&')
url = '{}://{}{}{}{}{}{}{}{}'.format(
    p.scheme, p.netloc, p.path,
    ';' if p.params else '', p.params,
    '?' if p.query else '', query,
    '#' if p.fragment else '', p.fragment)
response = urllib.request.urlopen(url)

Recommended Posts

Lors de l'accès à une URL contenant du japonais (URL japonais) avec python3 avec urllib, elle sera encodée arbitrairement avec html et une erreur se produira, alors notez la solution de contournement
Obtenez le cours de l'action d'une entreprise japonaise avec Python et faites un graphique
[Python] Si vous créez un fichier avec le même nom que le module à importer, une erreur d'attribut se produira.
J'ai essayé de trouver la différence entre A + = B et A = A + B en Python, alors notez
Lorsque j'essaie d'exécuter la commande make de Makefile avec os / exec de golang, la deuxième exécution et les suivantes entraînent une erreur.
Je suis tombé sur un filtre d'image avec un nom clairement japonais appelé filtre Kuwahara, et quand je l'ai essayé, c'était incroyable, alors je vais le présenter.
[Python] N'est-ce pas le plus élevé et le plus élevé si vous pouvez saisir les caractéristiques d'une entreprise avec nlplot?
[Python] Précautions lors de la recherche des valeurs maximum et minimum avec un tableau numpy avec un petit nombre d'éléments
Transformez un programme Python en démon et exécutez-le automatiquement au démarrage du système d'exploitation
Vous serez ingénieur dans 100 jours - Jour 29 - Python - Bases du langage Python 5
Vous serez ingénieur dans 100 jours - Jour 33 - Python - Bases du langage Python 8
Vous serez ingénieur dans 100 jours --Jour 26 --Python --Basiques du langage Python 3
Vous serez ingénieur dans 100 jours --Jour 32 --Python --Basiques du langage Python 7
Vous serez ingénieur dans 100 jours --Jour 28 --Python --Les bases du langage Python 4
Une introduction au logiciel d'interface graphique de la plate-forme de classe fait avec Python / Tkinter! (Et de nombreux Try and Error)! (Au milieu de l'écriture)
[Note] Exportez le html du site avec python.
Copiez la liste en Python
Le résultat de la création d'un album de cartes de jeunes mariés italiens en Python et de son partage
Je n'aime pas être frustré par la sortie de Pokemon Go, j'ai donc créé un script pour détecter la sortie et le tweeter
Un script qui envoie un ping au serveur enregistré et envoie un e-mail avec Gmail un certain nombre de fois en cas d'échec
J'ai écrit python3.4 dans .envrc avec direnv et je l'ai autorisé, mais j'ai eu une erreur de syntaxe
Notez ce que vous voulez faire à l'avenir avec Razpai
Lors de la lecture d'une image avec SimpleITK, il y a un problème s'il y a du japonais dans le chemin
Obtenez de manière récursive la liste Excel dans un dossier spécifique avec python et écrivez-la dans Excel.
VisibleDeprecation Avertissement: l'utilisation d'un nombre non entier au lieu d'un entier entraînera une erreur dans le futur
Renvoyez les données d'image avec Flask of Python et dessinez-les dans l'élément canvas de HTML
Un moyen simple de visualiser le temps pris en Python et un moyen plus intelligent de l'améliorer
Précautions lors de la saisie à partir de CSV avec Python et de la sortie vers json pour faire exe
Comment écrire quand on veut mettre un nombre après le numéro de groupe à remplacer par une expression régulière dans re.sub de Python