gpt4 book ai didi

html - 如何修复不兼容的 HTML 以便 Expat 解析它(htmltidy 不工作)

转载 作者:行者123 更新时间:2023-11-28 04:15:16 25 4
gpt4 key购买 nike

我正在尝试从 http://www.nfl.com/scores 中抓取信息(特别是找出游戏何时结束,以便我的计算机可以停止记录)。我可以很容易地下载 HTML,它声称符合标准:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

但是

  1. 尝试用 Expat 解析它产生错误 not well-formed (invalid token)

  2. W3C's online validation service报告 399 条错误和 121 条警告。

  3. 我尝试使用 -xml 选项在我的 Linux 系统上运行 HTML tidy(称为 tidy),但 tidy 报告了 56 条警告和 117 条错误,并且无法恢复良好的 XML 文件。错误如下所示:

    line 409 column 122 - Warning: unescaped & or unknown entity "&role"
    ...
    line 409 column 172 - Warning: unescaped & or unknown entity "&tabSeq"
    ...
    line 1208 column 65 - Error: unexpected </td> in <br>
    line 1209 column 57 - Error: unexpected </tr> in <br>
    line 1210 column 49 - Error: unexpected </table> in <br>

    但是当我检查输入时,“未知实体”似乎是正确引用的 URL 的一部分,所以我不知道是某处缺少双引号还是什么。

我知道那里有东西可以解析这些东西,因为 Firefox 和 w3m 都显示了一些合理的东西。 什么工具可以修复不兼容的 HTML,以便我可以使用 Expat 对其进行解析?

最佳答案

他们在计分框上使用了某种 Javascript,因此您将不得不使用更聪明的技巧(我的换行符):

/* box of awesome */
// iscurrentweek ? true;
(new nfl.scores.Game('2009112905','54635',{state:'pre',container:'scorebox-2009112905',
wrapper:'sb-wrapper-2009112905',template:($('scorebox-2009112905').innerHTML),homeabbr:'NYJ',
awayabbr:'CAR'}));

但是,为了回答您的问题,BeautifulSoup 解析它(看似)很好:

fp = urlopen("http://www.nfl.com/scores")
data = ""
while 1:
r = fp.read()
if not r:
break
data += r
fp.close()

soup = BeautifulSoup(data)
print soup.contents[2].contents[1].contents[1]

输出:

<title>NFL Scores: 2009 - Week 12</title>

可能更容易抓取 Yahoo's NFL scoreboard ,在我看来......事实上,去试试吧。


编辑:以您的问题为借口开始学习 BeautifulSoup。 Alex Martelli 一直对其赞不绝口,所以我认为它值得一试 -- 伙计,我印象深刻。

无论如何,我能够从 Yahoo!记分牌,像这样:

def main():
soup = BeautifulSoup(YAHOO_SCOREBOARD)
on_first_team = True
scores = []
hold = None

# Iterate the tr that contains a team's box score
for item in soup(name="tr", attrs={"align": "center", "class": "ysptblclbg5"}):
# Easy
team = item.b.a.string

# Get the box scores since we're industrious
boxscore = []
for quarter in item(name="td", attrs={"class": "yspscores"}):
boxscore.append(int(quarter.string))

# Final score
sub = item(name="span", attrs={"class": "yspscores"})[0]
if sub.b:
# Winning score
final = int(sub.b.string)
else:
data = sub.string.replace("&nbsp;", "")
if ":" in data:
# Catch TV: XXX and 0:00pm ET
final = None
else:
try: final = int(data)
except: final = None

if on_first_team:
hold = { team : (boxscore, final) }
on_first_team = False
else:
hold[team] = (boxscore, final)
scores.append(hold)
on_first_team = True

for game in scores:
print "--- Game ---"
for team in game:
print team, game[team]

我会在星期天对它进行调整,看看它是如何运作的,因为它真的很粗糙。这是它现在输出的内容:

--- Game ---
Green Bay ([0, 13, 14, 7], 34)
Detroit ([7, 0, 0, 5], 12)
--- Game ---
Oakland ([0, 0, 7, 0], 7)
Dallas ([3, 14, 0, 7], 24)

看看那个,我也获得了盒子分数...对于尚未发生的游戏,我们得到:

--- Game ---
Washington ([], None)
Philadelphia ([], None)

总之,一个让你跳的木桩。祝你好运。

关于html - 如何修复不兼容的 HTML 以便 Expat 解析它(htmltidy 不工作),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1814731/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com