/ / Jak naprawić niezgodny HTML, aby Expat go przeanalizował (htmltidy nie działa) - html, xml, htmltidy, expat-parser

Jak naprawić niezgodny HTML, aby Expat go przeanalizował (htmltidy nie działa) - html, xml, htmltidy, expat-parser

Próbuję zeskrobać informacje http://www.nfl.com/scores (w szczególności dowiedz się, kiedy gra się skończyła, więc mój komputer może przestać ją nagrywać). Mogę łatwo pobrać kod HTML i sprawia, że ​​to oświadczenie o zgodności ze standardami:

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

Ale

  1. Próba przeanalizowania go Expat powoduje błąd not well-formed (invalid token).

  2. The Usługa walidacji online W3C zgłasza 399 błędów i 121 ostrzeżeń.

  3. Próbowałem uruchomić HTML tidy (właśnie wywołany tidy) w moim systemie Linux za pomocą -xml opcja, ale uporządkowane raporty 56 ostrzeżeń i 117 błędów i nie jest w stanie odzyskać dobrego pliku XML. Błędy wyglądają tak:

    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>
    

    Ale kiedy sprawdzam dane wejściowe, „nieznane jednostki” wydają się być częścią prawidłowo cytowanego adresu URL, więc nie wiem, czy gdzieś brakuje jakiegoś podwójnego cudzysłowu.

Wiem, że tak coś tam można analizować te rzeczy, ponieważ zarówno Firefox, jak i w3m wyświetlają coś rozsądnego. Jakie narzędzie naprawi niezgodny kod HTML, aby móc go przeanalizować za pomocą Expat?

Odpowiedzi:

3 dla odpowiedzi № 1

Na górze nfl.com znajduje się tablica wyników automatycznej aktualizacji oparta na technologii Flash. Znajduje się pewien monitoring jej ruchu sieciowego:

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

Prawdopodobnie będzie to nieco łatwiejsze do przeanalizowania niż tablica wyników HTML.


4 dla odpowiedzi nr 2

Używają Javascript w polach wyników, więc będziesz musiał grać w bardziej sprytne sztuczki (moje łamanie wierszy):

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

Jednak, aby odpowiedzieć na twoje pytanie, BeautifulSoup analizuje je (pozornie) w porządku:

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]

Wyjścia:

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

Może być łatwiej skrobać Tablica wyników NFL Yahoo, moim zdaniem ... w rzeczywistości, spróbuj.


EDYTOWAĆ: Użyłeś swojego pytania jako pretekstu do nauki BeautifulSoup. Alex Martelli śpiewał swoje pochwały, więc pomyślałem, że warto spróbować - człowieku, jestem pod wrażeniem.

W każdym razie udało mi się przygotować podstawowy skrobak wyników z Yahoo! tablica wyników, tak:

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]

Zmieniłbym to w niedzielę, aby zobaczyć, jak działa, ponieważ jest „bardzo szorstki. Oto, jak wygląda teraz:

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

Spójrz na to, ja też zaszufladkowałem wyniki skrzynek ... za grę, która jeszcze się nie wydarzyła, dostajemy:

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

Tak czy inaczej, kołek, z którego możesz skoczyć. Powodzenia.


2 dla odpowiedzi nr 3

Zbadać tagsoup. Jeśli chcesz skończyć z drzewem DOM lub strumieniem SAX w Javie, jest to bilet. Jeśli chcesz wyodrębnić konkretne informacje, Piękna Zupa jest Piękną Rzeczą.