2009-11-29 12 views
1

J'essaie de récupérer des informations de http://www.nfl.com/scores (en particulier, savoir quand une partie est terminée afin que mon ordinateur puisse arrêter d'enregistrer). Je peux télécharger le code HTML assez facilement, et rend cette allégation au sujet de la conformité aux normes:Comment corriger le HTML non-conforme pour que Expat l'analyse (htmltidy ne fonctionne pas)

<!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"> 

Mais

  1. Une tentative pour analyser avec Expat produit l'erreur not well-formed (invalid token). Le W3C's online validation service signale 399 erreurs et 121 avertissements.

  2. J'ai essayé de courir HTML bien rangé (juste appelé tidy) sur mon système Linux avec l'option -xml, mais les rapports bien rangé 56 avertissements et 117 erreurs et ne parvient pas à récupérer un bon fichier XML. Les erreurs ressemblent à ceci:

    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> 
    

    Mais quand je vérifie l'entrée, les « entités inconnues » semblent faire partie d'une URL correctement cité, donc je ne sais pas si un guillemet manque quelque part ou ce .

Je sais qu'il ya quelque chose là-bas qui peut analyser ce genre de choses parce que Firefox et affichage w3m quelque chose de raisonnable. Quel outil corrigera le code HTML non conforme pour que je puisse l'analyser avec Expat?

+0

wtf est Expat? un gars qui vit à l'étranger? – JohnIdol

+0

avez-vous essayé le service de validation w3c? -> http://validator.w3.org/#validate_by_input – JohnIdol

+1

Expat est une bibliothèque d'analyse XML. –

Répondre

3

Il existe un tableau de bord de mise à jour automatique basé sur Flash en haut de la page nfl.com. Certains suivi de son trafic réseau trouve:

http://www.nfl.com/liveupdate/scorestrip/ss.xml

Ce sera probablement un peu plus facile à analyser que le tableau de bord HTML.

+0

Très intelligent, et plus facile à analyser en effet. Je me demande si cela mènera à une course aux armements, cependant. –

+0

Cela ne répond pas vraiment à la question posée, mais cela a été si utile pour mon vrai problème que je l'ai marqué comme la réponse acceptée. Merci!!!!!! –

4

Ils utilisent une sorte de Javascript sur les cases de score, donc vous allez devoir jouer des tours plus intelligents (ligne le mien casse):

/* 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'})); 

Cependant, pour répondre à votre question, BeautifulSoup il parse (apparemment) très bien:

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] 

Sorties:

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

Pourrait être plus facile de gratter Yahoo's NFL scoreboard, à mon avis ... en fait, off pour l'essayer.


EDIT: occasion votre question comme une excuse pour se déplacer à l'apprentissage BeautifulSoup. Alex Martelli a chanté ses louanges, alors je me suis dit que ça valait la peine d'essayer - mec, je suis impressionné.

Quoi qu'il en soit, j'ai été capable de préparer un grattoir de score rudimentaire de Yahoo! tableau de bord, comme ça:

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] 

Je voudrais régler ce dimanche pour voir comment cela fonctionne, car il est très difficile. Voici ce qu'il génère en ce moment:

--- 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) 

Regardez, j'ai aussi obtenu des scores de boîte ...pour un jeu qui n'a pas encore eu lieu, nous obtenons:

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

Quoi qu'il en soit, une cheville pour vous de sauter à partir. Bonne chance.

+0

BeautifulSoup est génial! +1 –

+0

Oh, oui, la soupe. C'est aussi bon. – bmargulies

+0

Je l'ai vérifié et BeautifulSoup nettoie presque complètement le HTML, mais le XML qu'il contient contient toujours 5 erreurs. (C'est avec la sortie utilisant la méthode 'prettify'.) Je suis un peu réticent à aller trop loin dans la soupe puisque le reste de mon infrastructure est en Lua, donc je vais probablement essayer le flux xml en premier. Mais c'est toujours une bonne chose à savoir. –

2

Regardez dans tagsoup. Si vous voulez vous retrouver avec un arbre DOM ou un flux SAX en Java, c'est le ticket. Si vous voulez juste extraire des informations spécifiques, Beautiful Soup est une belle chose.

+0

Cela semble très utile, bien que le paquet Debian ne puisse pas être exécuté. Grrrr. +1, merci. –

+0

En règle générale, je n'utilise jamais Java via Debian. – bmargulies