UnicodeEncodeError: 'ascii'编解码器无法对字符u'\xb0'进行编码,位于第11个位置:该序号不在128的范围内。

3

我正在学习使用Nathan Yau的书《Visualize This》来爬取数据。我试图爬取2009年的Wunderground数据,但是出现了这个错误。它说超出了范围,但是我不知道为什么。

line 43, in <module>
    f.write(timestamp + ',' + dayTemp + '\n')
UnicodeEncodeError: 'ascii' codec can't encode character u'\xb0' in position 11: ordinal not in range(128)

以下是我的代码:
import sys
import urllib2
from bs4 import BeautifulSoup as BS

# Create/open a file called wunder.txt (which will be a comma-delimited file)
f = open('wunder-data.txt', 'w')

# Iterate through months and day
for m in range(1, 13):
  for d in range(1, 32):

  # Check if already gone through month
    if (m == 2 and d > 28):
     break
    elif (m in [4, 6, 9, 11] and d > 30):
     break

  # Open wunderground.com url
  url = "http://www.wunderground.com/history/airport/KBUF/2009/" + str(m) + "/" + str(d) + "/DailyHistory.html"
  page = urllib2.urlopen(url)

  # Get temperature from page
  soup = BS(page,"html.parser")
  # dayTemp = soup.body.nobr.b.string
  dayTemp = soup.find("span", text="Mean Temperature").parent.find_next_sibling("td").get_text(strip=True)

  # Format month for timestamp
  if len(str(m)) < 2:
    mStamp = '0' + str(m)
  else:
    mStamp = str(m)

  # Format day for timestamp
  if len(str(d)) < 2:
    dStamp = '0' + str(d)
  else:
    dStamp = str(d)

  # Build timestamp
  timestamp = '2009' + mStamp + dStamp

  # Write timestamp and temperature to file
  f.write(timestamp + ',' + dayTemp + '\n')

# Done getting data! Close file.
f.close()

尝试使用open('wunder-data.txt', 'w', encoding='utf8')打开文件。 - juanpa.arrivillaga
谢谢!但是出现了新的问题。第六行,在<module>中: open('wunder-data.txt', 'w', encoding='utf8') TypeError:对于此函数,'encoding'是无效的关键字参数。 - Xinya Wang
糟糕,刚刚注意到你正在使用Python2。 - juanpa.arrivillaga
我该怎么办?我是Python的新手。谢谢! - Xinya Wang
你可以使用 import io,然后使用 io.open('wunder-data.txt', 'w', encoding='utf8') 代替内置的 open。如果你是初学者,应该考虑使用 Python 3 而不是 Python 2。 - juanpa.arrivillaga
显示剩余2条评论
2个回答

2
问题是度数符号。那是你的u'\xb0'字符。 juanpa.arrivillaga's comment正确,你应该使用文件编码。在Python 2中最简单的方法是:
from codecs import open

那么这应该没问题:
open('wunder-data.txt', 'w', encoding='utf8')

我担心这不是唯一的 Unicode 或非 ASCII 编码问题会困扰你。现在世界上使用的是 Unicode,而 Python 3 更擅长处理 Unicode。虽然在 Python 2 中也可以实现,但需要更多的小心和关注。尽管如此,codecs 模块应该可以帮助你解决眼前的困境。

谢谢!但是我现在有一个新问题。哦,好累啊。它说:第44行,在<module>中 f.write(timestamp + ',' + dayTemp + '\n') NameError: name 'f' is not defined - Xinya Wang
@XinyaWang 请考虑为对你有帮助的答案点赞,或者将其中一个标记为“首选答案”(通过点击答案左上角的勾号)。 - Jonathan Eunice

2
在这个函数调用中:
f.write(timestamp + ',' + dayTemp + '\n')

timestamp',''\n'str 对象,而 dayTempunicode

strunicode 的总和是一个 unicode 对象。请注意,如果 str 对象不仅限于 ASCII 字符,则此操作将失败。

在这种情况下,代码实际上执行类似以下内容(\xb0 代表 °):

f.write(u'20090305,11\xb0\n')

这样做的问题在于,Unicode字符不能直接写入文件。它们只是一种抽象的概念,没有一种唯一的格式可以将其写入文件*。你必须选择一种格式。通常最好的选择是UTF-8。
s = (timestamp + ',' + dayTemp + '\n').encode('utf-8')
# or, cleaner:
s = u'{},{}\n'.format(timestamp, dayTemp).encode('utf-8')
f.write(s)

另一种选项是拥有一个更聪明的file对象,它会自动将unicode编码为UTF-8,正如其他人所建议的:

with io.open('wunder-data.txt', 'w', encoding='utf-8') as f:
    f.write(timestamp + ',' + dayTemp + '\n')

或者

with io.open('wunder-data.txt', 'w', encoding='utf-8') as f:
    f.write(timestamp + ',' + dayTemp + '\n')

* 实际上,ASCII是唯一独特的格式,但只有当所有字符都可以用ASCII表示时才有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接