Expatがそれを解析するように非準拠のHTMLを修正する方法
-
06-07-2019 - |
質問
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">
しかし
-
Expat で解析しようとすると、エラー
not-formed (無効なトークン)
。 -
W3Cのオンライン検証サービスは、399エラーと121警告を報告します。
-
-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の両方が適切なものを表示するため、このようなものを解析できる何かがあることを知っています。 Expatで解析できるように、非準拠のHTMLを修正するツールはどれですか?
解決
nfl.comの上部にはFlashベースの自動更新スコアボードがあります。ネットワークトラフィックの監視により、次のことがわかります。
http://www.nfl.com/liveupdate/scorestrip/ss.xml
おそらく、HTMLスコアボードよりも解析が少し簡単になります。
他のヒント
スコアボックスで何らかの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のNFLスコアボードを簡単に削ることができます。 、オフにして試してみてください。
編集:あなたの質問を口実として使用して、BeautifulSoupを学習します。アレックス・マルテッリは賞賛を歌っているので、試してみる価値があると思いました-男、私は感銘を受けました。
とにかく、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(" ", "")
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)
とにかく、ジャンプするためのペグです。幸運を祈ります。
tagsoup をご覧ください。 JavaでDOMツリーまたはSAXストリームを作成したい場合、それがチケットです。特定の情報のみを抽出したい場合、Beautiful Soupは美しいものです。