使用urllib导入格式不正确的文本文件

1 投票
4 回答
660 浏览
提问于 2025-04-16 19:46

我正在尝试使用 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 个回答

0

假设 s 里有你表格的一行数据。你可以使用 re(正则表达式)库里的 split() 方法来处理它:

import re
rexp = re.compile('  +')  # Match two or more spaces
cols = rexp.split(s)

...这样,cols 就变成了一个字符串列表,每个字符串代表表格中的一列。这是基于表格的列之间至少有两个空格,并且没有其他分隔符。如果不是这样,你可以修改 re.compile() 的参数来适应其他情况。

记住,Python 把文件看作是一系列的行,这些行是用换行符分开的。因此,你只需要对文件进行循环,针对每一行使用 .split() 方法。

如果想要更优雅的解决方案,可以看看内置的 map() 函数,试着用它来替代 for 循环。

0

显然,你只需要在多个空格上进行分割。可惜的是,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()
2

想看看最好的解决方案吗?点击这个链接 http://www.boydsworld.com/cgi/scores.pl?team1=all&team2=all&firstyear=2011&lastyear=2011&format=CSV&submit=Fetch,你会得到一个很不错的CSV文件,完全不需要什么复杂的操作。

撰写回答