关于python:UnicodeEncodeError:’ascii’编解码器不能编码15-17位的字符:ord inal不在范围内(128)

UnicodeEncodeError: 'ascii' codec can't encode characters in position 15-17: ord inal not in range(128)

我在运行以下代码方面遇到了困难。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import urllib.request, urllib.parse, urllib.error
from bs4 import BeautifulSoup
import ssl
import re
import csv

file = open("Test.CSV","r")
reader = csv.reader(file)
for line in reader:
    text = line[5]
    lst = re.findall('(http.?://[^\s]+)', text)

    if not lst: print('Empty List')
    else:
        try:
            for url in lst:
                html = urllib.request.urlopen(url, context=ctx).read()
                soup = BeautifulSoup(html, 'html.parser')
                title = soup.title.string
                str_title = str (title)
                if 'Twitter' in str_title:
                    if len(lst) > 1: break
                    else: continue
                else:
                    print (str_title, ',', url)
        except urllib.error.HTTPError as err:
            if err.code == 404:
                print ('Invalid Twitter Link')

上面提到的代码读取一个csv文件,选择一个列,然后使用regex解析一行中的所有超链接,然后使用beautifulsoup解析超链接以获取页面的"标题字符串"。

现在,每当我运行此代码时,它就会停止对特定行的工作,并抛出一个错误"unicodeencodeerror:'ascii'codec can't encode characters in position 15-17:ordinal not in range(128)"。

这里如何处理Unicode字符串?任何帮助都将不胜感激。


错误消息显示问题发生在urllib.request.urlopen(url, context=ctx)中。看起来至少有一个URL包含非ASCII字符。

怎么办?

您可以尝试引用URL:

1
html = urllib.request.urlopen(urllib.parse.quote(url, errors='ignore'), context=ctx).read()

这将阻止UnicodeEncodeError,但将静默地构建一个错误的URL,这可能会导致以后出现问题。

我的建议是捕获unicodeencodeerror并显示一条错误消息,这将有助于了解引擎盖下发生的情况以及如何实际修复它:

1
2
3
4
5
6
7
8
for url in lst:
    try:
        html = urllib.request.urlopen(url, context=ctx).read()
        soup = BeautifulSoup(html, 'html.parser')
        title = soup.title.string
        ...
    except UnicodeEncodeError as e:
        print("Incorrect URL {}".format(url.encode('ascii', errors='backslashreplace')))

errors='backslashreplace'选项将转储违规字符的代码。