使用urllib导入格式不正确的文本文件
我正在尝试使用 urllib
从网站上解析一个文本文件并提取数据。我之前处理过其他文件,它们的格式是按列排列的文本,但这个文件让我有点困惑,因为Southern Illinois-Edwardsville这一行把第二个得分和位置挤出了列。
file = urllib.urlopen('http://www.boydsworld.com/cgi/scores.pl?team1=all&team2=all&firstyear=2011&lastyear=2011&format=Text&submit=Fetch')
for line in file:
game_month = line[0:1].rstrip()
game_day = line[2:4].rstrip()
game_year = line[5:9].rstrip()
team1 = line[11:37].rstrip()
team1_scr = line[38:40].rstrip()
team2 = line[42:68].rstrip()
team2_scor = line[68:70].rstrip()
extra_info = line[72:100].rstrip()
Southern Illinois-Edwardsville这一行把'il'导入为team2_scr,并把' 4 @Central Arkansas'导入为extra_info。
4 个回答
假设 s
里有你表格的一行数据。你可以使用 re
(正则表达式)库里的 split() 方法来处理它:
import re
rexp = re.compile(' +') # Match two or more spaces
cols = rexp.split(s)
...这样,cols 就变成了一个字符串列表,每个字符串代表表格中的一列。这是基于表格的列之间至少有两个空格,并且没有其他分隔符。如果不是这样,你可以修改 re.compile() 的参数来适应其他情况。
记住,Python 把文件看作是一系列的行,这些行是用换行符分开的。因此,你只需要对文件进行循环,针对每一行使用 .split() 方法。
如果想要更优雅的解决方案,可以看看内置的 map() 函数,试着用它来替代 for 循环。
显然,你只需要在多个空格上进行分割。可惜的是,csv
模块只允许使用单个字符作为分隔符,不过re.sub
可以帮你解决这个问题。我建议你可以这样做:
import urllib2
import csv
import re
u = urllib2.urlopen('http://www.boydsworld.com/cgi/scores.pl?team1=all&team2=all&firstyear=2011&lastyear=2011&format=Text&submit=Fetch')
reader = csv.DictReader((re.sub(' {2,}', '\t', line) for line in u), delimiter='\t', fieldnames=('date', 'team1', 'team1_score', 'team2', 'team2_score', 'extra_info'))
for i, row in enumerate(reader):
if i == 5: break # Only do five (otherwise you don't need ``enumerate()``)
print row
这样会产生像这样的结果:
{'team1': 'Air Force', 'team2': 'Missouri State', 'date': '2/18/2011', 'team2_score': '2', 'team1_score': '7', 'extra_info': '@neutral'}
{'team1': 'Akron', 'team2': 'Lamar', 'date': '2/18/2011', 'team2_score': '1', 'team1_score': '2', 'extra_info': '@neutral'}
{'team1': 'Alabama', 'team2': 'Alcorn State', 'date': '2/18/2011', 'team2_score': '0', 'team1_score': '11', 'extra_info': '@Alabama'}
{'team1': 'Alabama State', 'team2': 'Tuskegee', 'date': '2/18/2011', 'team2_score': '5', 'team1_score': '9', 'extra_info': '@Alabama State'}
{'team1': 'Appalachian State', 'team2': 'Maryland-Eastern Shore', 'date': '2/18/2011', 'team2_score': '0', 'team1_score': '4', 'extra_info': '@Appalachian State'}
或者如果你更喜欢的话,可以直接使用cvs.reader
,这样你得到的就是list
而不是dict
:
reader = csv.reader((re.sub(' {2,}', '\t', line) for line in u), delimiter='\t')
print reader.next()
想看看最好的解决方案吗?点击这个链接 http://www.boydsworld.com/cgi/scores.pl?team1=all&team2=all&firstyear=2011&lastyear=2011&format=CSV&submit=Fetch,你会得到一个很不错的CSV文件,完全不需要什么复杂的操作。