Python 3.4.0 -- 'ascii' 编解码器无法对位置 11-15 中的字符进行编码:序号不在范围内 (128) -- Unix 14.04

Python 3.4.0 -- 'ascii' codec can't encode characters in position 11-15: ordinal not in range(128) -- Unix 14.04

尝试使用 urlib 和 lxml 从 Web 检索一些数据,我遇到了一个错误,不知道如何修复它。

url='http://sum.in.ua/?swrd=автор'
page = urllib.request.urlopen(url)

错误本身:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 11-15: ordinal not in range(128)

这次我在 API 中使用乌克兰语,但是当我在这里使用 API(其中没有任何乌克兰语字母)时:

url="http://www.toponymic-dictionary.in.ua/index.php?option=com_content&view=section&layout=blog&id=8&Itemid=9"
page = urllib.request.urlopen(url)
pageWritten = page.read()
pageReady = pageWritten.decode('utf-8')
xmldata = lxml.html.document_fromstring(pageReady)
text1 = xmldata.xpath('//p[@class="MsoNormal"]//text()')

它让我得到乌克兰语的数据,一切正常。

我相信你可以做如下的事情

 url = 'http://sum.in.ua/'
 q = 'swrd=автор'
 import urllib,requests
 requests.get(url+"?"+urllib.quote(q))

我认为 urllib.quote 会把 "swrd=автор" 变成类似 "swrd=%D0%B0%D0%B2%D1%82%D0%BE%D1%80"

的东西

应该可以接受

URLs 只能使用可打印 ASCII 代码点的子集;其他一切都必须使用 URL percent encoding.

正确编码

您最好让 Python 处理您的参数。 urllib.parse.urlencode() function 可以转换 字典 (或键值对序列)以供在 URL 中使用:

from urllib.parse import urlencode

url = 'http://sum.in.ua/'
parameters = {'swrd': 'автор'}
url = '{}?{}'.format(url, urlencode(parameters))

page = urllib.request.urlopen(url)

这将首先将参数编码为 UTF-8 字节,然后将这些字节转换为百分比编码序列:

>>> from urllib.parse import urlencode
>>> parameters = {'swrd': 'автор'}
>>> urlencode(parameters)
'swrd=%D0%B0%D0%B2%D1%82%D0%BE%D1%80'

如果您没有自己构建 URL,则需要 'repair' 编码。您可以拆分查询字符串,将其解析为字典,然后将其传递给 urlencode,然后使用 urllib.parse.urlparse() and urllib.parse.parse_qs():

将其放回 URL
from urllib.parse import urlparse, parse_qs, urlencode

url = 'http://sum.in.ua/?swrd=автор'
parsed_url = urlparse(url)
parameters = parse_qs(parsed_url.query)
url = parsed_url._replace(query=urlencode(parameters, doseq=True)).geturl()

这会将 URL 拆分为其组成部分,解析出查询字符串,然后重新编码并重新构建 URL:

>>> from urllib.parse import urlparse, parse_qs, urlencode
>>> url = 'http://sum.in.ua/?swrd=автор'
>>> parsed_url = urlparse(url)
>>> parameters = parse_qs(parsed_url.query)
>>> parsed_url._replace(query=urlencode(parameters, doseq=True)).geturl()
'http://sum.in.ua/?swrd=%D0%B0%D0%B2%D1%82%D0%BE%D1%80'