刮擦后写入CSV时出现Unicode编码错误

时间:2014-10-08 23:28:10

标签: python python-2.7

我正在学习网络抓取,并且练习我正试图从棒球参考中搜集Derek Jeter的棒球统计数据表。使用beautifulsoup,我能够像这样提取表格:

from bs4 import BeautifulSoup
import urllib2

jeter = "http://www.baseball-reference.com/players/j/jeterde01-bat.shtml"
page = urllib2.urlopen(jeter)
soup = BeautifulSoup(page)

table = soup.find('table', id='batting_standard')

#create a list of the header names
tableheaders = table.find_all('th')


headers = []
i = 0
while i < 30:
    headers.append(tableheaders[i].get_text())
    i = i + 1

#map the data points to a json file
data_points = table.find_all('tr', { 'class' : 'full' })
table_rows = []
row_num = 0
for row in data_points:
    cells = row.find_all('td')
    #for each 'tr', assign each 'td' to an entry in the json.
    table_rows.append([])
    for i in range(0, len(cells) - 1):
        table_rows[row_num].append(cells[i].get_text())
    row_num = row_num + 1

table_rows最终成为一个列表,其中每个元素是另一个表示表格每一行的列表:

table_rows = [['a','b','c'],['d','e','f']]

然后,当我尝试使用此代码将其写入CSV时:

导入csv

with open('/home/russell/Desktop/Python Learning/Web Scraping/jeter.csv', 'wb') as fp:
    a = csv.writer(fp)
    #write the headers for the csv file
    a.writerow(headers) 
    for e in table_rows:
        a.writerow(e)

我收到以下错误消息:

Traceback (most recent call last):
  File "/home/russell/Documents/Python Learning/Web Scraping/jeter_scrape2.py", line 39, in <module>
    a.writerow(e)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 4-5: ordinal not in range(128)

我对这一切都不熟悉,所以您提供的任何见解都将非常感激。

注意:我使用的是Python 2.7

修改

将它挂起的一行是:

[u'1998\xa0\u2605', u'24', u'NYY', u'AL', u'149', u'694', u'626', u'127', u'203', u'25', u'8', u'19', u'84', u'30', u'6', u'57', u'119', u'.324', u'.384', u'.481', u'.864', u'127', u'301', u'13', u'5', u'3', u'3', u'1', u'*6']

我认为它是第一项中的斜线? (U&#39; 1998 \ XA0 \ u2605&#39)。它应该是一年 - 1998年.csv作者可以处理前几行,但会挂在那一行。

2 个答案:

答案 0 :(得分:0)

问题是你正在抓取的HTML表包含字符U + 2605 BLACK STAR。您可以在“1999”旁边的页面上清楚地看到它。您可以通过简单地从第一列中删除这些位来轻松解决此问题:

for e in table_rows:
    e[0] = e[0].replace(u'\xa0\u2605', u'')
    a.writerow(e)

类似的东西。

答案 1 :(得分:0)

Python 2中的

cvs模块使用字节。您必须自己编码Unicode文本。试试writer.writerow([item.encode('utf-8') for item in row])