在出现此错误之前,抓取工作正常:“ascii”编解码器无法将字符u“\u2122”编码到位

2024-09-29 01:19:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我只有几个星期的python训练,所以我怀疑有一个简单的解决方案。但对我来说,这是相当令人沮丧的,工作了几个小时后,我现在请求你的帮助!

我正在尝试清理的网站组织得很好(请参见https://twam2dcppennla6s.onion.to/),我编写的代码将清理26页中的大约一半,直到我收到以下错误消息:

Traceback (most recent call last):
  File "SR2works4real2.py", line 18, in <module>
    csvWriter.writerows(jsonObj['vendors'])
  File "/usr/lib/python2.7/csv.py", line 154, in writerows
    return self.writer.writerows(rows)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2122' in position 8: ordinal not in range(128)

我的代码是:

import urllib2, json,csv
htmlTxt=""


urlpart1='https://twam2dcppennla6s.onion.to/vendors.php?_dc=1393967362998&start='
pageNum=0   
urlpart2='&limit=30&sort=%5B%7B%22property%22%3A%22totalFeedback%22%2C%22direction%22%3A%22DESC%22%7D%5D'
csvFile=open('S141.csv','wb')
csvWriter=csv.DictWriter(csvFile,['name','vendoringTime','lastSeen','avgFeedback','id','totalFeedback','united','shipsTo','shipsFrom'],delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
csvWriter.writeheader()

while htmlTxt != "{\"vendors\":[]}":
    print("Page "+str(pageNum)+"...")
    pageNum+=30
    response=urllib2.urlopen((urlpart1)+str(pageNum)+(urlpart2))
    htmlTxt=response.read()
    htmlTxt.encode('utf-8')
    jsonObj=json.loads(htmlTxt)
    csvWriter.writerows(jsonObj['vendors'])

    #print(str(jsonObj))

csvFile.close()

我希望有人能帮忙!


Tags: csvtocsvfile代码inhttpsstrcsvwriter
2条回答

jsonObj中的字符串将是unicode类型,因为Pythonjson模块将生成unicode字符串。你的csv作者想要的一切都是str类型的。在Python2.7中,它将尝试自动将unicode类型转换为str类型(假定为ASCII)。如果unicode类型不包含ASCII,这当然会失败。

最简单的解决方法是更改这一行:

csvWriter.writerows(jsonObj['vendors'])

在发送给csv writer之前,用utf8将unicode编码成str。jsonObj['vendors']是具有unicode键和值的字典列表,因此我们可以执行以下操作:

unicode_vendors = jsonObj['vendors']
str_vendors = []
for unicode_dict in unicode_vendors:
    str_dict = {}
    for key, value in unicode_dict.items():
        str_dict[key.encode('utf8')] = value.encode('utf8') if value else value
    str_vendors.append(str_dict)
csvWriter.writerows(str_vendors)

这是用于商标符号的unicode:http://www.marathon-studios.com/unicode/U2122/Trade_Mark_Sign

由于您正在抓取web,您可能会看到更多此类错误,因此替换它可能适用于此页,但不能用其他符号替换其他页。

csv模块正在将unicode转换为ascii,然后再编写它。我建议你在发短信之前也这样做,自己把它清理干净,也就是说,不要

htmlTxt.encode('utf-8')

htmlTxt.encode('ascii', 'ignore')

然后检查文本,看它是否适合您的目的。

编辑

以下是我在Python 3中的输出:

>>> u'\u2122'.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\u2122' in position 0: ordinal not in range(128)
>>> u'\u2122'.encode('ascii', 'ignore')
b''

和Python2.6:

>>> u'\u2122'.encode('ascii')
Traceback (most recent call last):
  File "<pyshell#92>", line 1, in <module>
    u'\u2122'.encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2122' in position 0: ordinal not in range(128)
>>> u'\u2122'.encode('ascii', 'ignore')
''

相关问题 更多 >