UnicodeEncodeError:' ascii'编解码器不能对字符u' \ xb0'进行编码。位置11:序数不在范围内(128)

时间:2017-03-12 08:16:05

标签: python

我正在学习如何使用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()

2 个答案:

答案 0 :(得分:1)

问题是the degree symbol。那是你的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模块应该可以帮助您摆脱紧急危机。

答案 1 :(得分:1)

在此函数调用中:

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表示时才有效。