Wie nicht-konformen HTML zu beheben, so Expat es analysieren wird (htmltidy nicht funktioniert)

StackOverflow https://stackoverflow.com/questions/1814731

Frage

Ich versuche, Informationen zu kratzen von http://www.nfl.com/scores (insbesondere herausfinden, wann ein Spiel vorbei ist so mein Computer kann sie stoppen Aufnahme). Ich kann die HTML-Download leicht genug, und es macht diesen Anspruch über die Einhaltung von Standards:

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

Aber

  1. Ein Versuch, es zu analysieren, mit Expat erzeugt den Fehler not well-formed (invalid token).

  2. Die Online-Validierungsservice des W3C meldet 399 Fehler und Warnungen 121.

  3. habe ich versucht, HTML ordentlich (nur genannt tidy) auf meinem Linux-System mit dem -xml Option zu laufen, aber ordentlich Berichte 56 Warnungen und 117 Fehler und ist nicht in der Lage eine gute XML-Datei wiederherzustellen. Die Fehler wie folgt aussehen:

    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>
    

    Aber wenn ich die Eingabe zu überprüfen, die „unbekannten Wesen“ erscheinen Teil einer richtig zitiert URL zu sein, so dass ich weiß nicht, ob ein doppeltes Anführungszeichen irgendwo oder was fehlt.

Ich weiß, dass es etwas gibt, die dieses Zeug analysieren kann, weil sowohl Firefox und w3m Display etwas vernünftig. Welches Tool wird die nicht-konformen HTML beheben, so dass ich es mit Expat analysieren kann?

War es hilfreich?

Lösung

Es gibt ein Flash-basierte Auto-Aktualisierung in Führung, was an der Spitze der nfl.com. Einige Überwachung der Netzwerkverkehr findet:

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

Das wird wohl etwas einfacher sein als der HTML-Anzeigers zu analysieren.

Andere Tipps

Sie benutzen eine Art von JavaScript auf den Score-Boxen, so dass Sie mehr clevere Tricks (Zeilenumbrüche mich) haben werden spielen:

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

Allerdings zu beantworten Ihre Frage, BeautifulSoup parst sie (scheinbar) in Ordnung:

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]

Ausgänge:

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

könnte einfacher sein, zu kratzen Yahoo NFL Anzeiger , meiner Meinung nach ... in der Tat , weg, es zu versuchen.


EDIT: Gebraucht Ihre Frage als Vorwand zu bekommen um BeautifulSoup zu lernen. Alex Martelli hat sein Lob zu singen, so dass ich es dachte, einen Versuch wert -. Mann, bin ich beeindruckt

Wie auch immer, ich war in der Lage eine rudimentäre Punktzahl Schaber von der Yahoo! zu kochen Anzeiger, etwa so:

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]

Ich würde zwicken dies am Sonntag, um zu sehen, wie es funktioniert, wie es wirklich rau. Hier ist, was es gibt ab jetzt:

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

Sehen Sie sich das, ich Box Scores verhakt zu ... für ein Spiel, das noch nicht geschehen ist, erhalten wir:

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

Wie auch immer, ein Stift für Sie zu springen. Viel Glück.

Schauen Sie

tagsoup . Wenn Sie mit einem DOM-Baum oder einem SAX-Stream in Java, um am Ende wollen, dann ist es das Richtige. Wenn Sie nur bestimmte Informationen zu extrahieren, schöne Suppe ist eine schöne Sache.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top