2016-07-03 14 views
-1

existiert Ich versuche, einen Code zu schreiben, Daten von einer Website zu extrahieren mit Python und seine urllib2 und BeautifulSoup Bibliotheken.Python: Kann nicht Listenelement zugreifen, obwohl es

Ich habe versucht, über die Zeilen der gewünschten Tabelle zu iterieren und dann die Daten in jeder in "td" angegebenen Zeile in eine Listenvariable row_data zu speichern. Event obwohl ich die gesamte Liste zum Drucken bekommen kann, kann ich nicht auf die Liste bei bestimmten Indizes zugreifen, und der Interpreter wirft den Fehler "Listenindex außerhalb des Bereichs" auf. Hier geht mein Code und die Ausgabe.

import urllib2 
from bs4 import BeautifulSoup 

link = 'http://www.babycenter.in/a25008319/most-popular-indian-baby-names-of-2013' 
page = urllib2.urlopen(link) 
soup = BeautifulSoup(page) 
right_table = soup.find('table', class_= 'contentTable colborders') 
name=[] 
meaning=[] 
alternate=[] 

for row in right_table.find_all("tr"): 
    row_datas = row.find_all("td") 
    print row_datas 
    print row_datas[0] 

Ausgang:

[]Traceback (most recent call last): 
    File "C:\Users\forcehandler\Documents\python\data_scrape.py", line 41, in <module> 

print row_datas[0] 
IndexError: list index out of range 
[Finished in 1.6s] 

ich ähnlichen Code versucht, offensichtliche Fehler zu markieren, aber ohne Erfolg. Code:

i = [range(y,10) for y in range(5)] 
for j in i: 
    print j 
    print j[0] 

Ausgang:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
0 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 
1 
[2, 3, 4, 5, 6, 7, 8, 9] 
2 
[3, 4, 5, 6, 7, 8, 9] 
3 
[4, 5, 6, 7, 8, 9] 
4 

Ich bin neu in der Programmierung und konnte nicht finden anderswo helfen. Danke im Voraus!

Edit: Die '[]' vor Traceback möglicherweise versehentlich in die Ausgabe beim Kopieren und Einfügen eingefügt. Und danke für die hilfreichen Antworten/Vorschläge.

Lösung: Ich habe die Integrität der Daten vor der Verwendung nicht überprüft. Wie sich herausstellte, bestand die erste Zeile nur aus "th" -Werten und keinen "td" -Werten und daher dem Fehler.

Lektion: Testen Sie die Daten immer, bevor Sie sie verwenden.

Nebenbei bemerkt: Dies ist meine erste Frage zu StackOverflow und ich bin überwältigt von so schnellen, qualitativ hochwertigen und hilfreichen Antworten.

+0

ist 'drucken row_datas' eine leere Liste an jedem Punkt zeigt? –

+1

Ihre 'print row_datas' Zeile wurde vor dem Traceback' [] 'ausgedruckt (Sie haben' [] Traceback', nicht 'Traceback', möchten Sie vielleicht herausfinden, warum Sie keine Zeilenumbrüche zu drucken scheinen). Die Liste ist leer, es gibt kein Element am Index '0'. –

+0

Mit Blick auf diese Tabelle haben nur 50 von 52 Zeilen 'td' Elemente in ihnen; Es gibt zwei Zeilen mit "th" Header-Elementen. –

Antwort

2

Ihr Ausgang mindestens einer der Reihen zeigt, dass leer ist:

[]Traceback (most recent call last): 
^^ 

Das [] ist eine leere Liste, die Ausgabe wurde von Ihrer print row_datas Zeile produziert. Normalerweise würde ich erwarten, dass es eine neue Zeile zwischen dieser und der Traceback; Vielleicht haben Sie Ihre Ausgabe nicht korrekt kopiert, oder Sie haben eine Konsole, die einen größeren Puffer als Zeilenpufferung verwendet, was dazu führt, dass stdout und stderr gemischt werden.

Das ist, weil die erste dieser Zeilen th Kopfzellen in ihm statt:

>>> rows = soup.select('table.contentTable tr') 
>>> rows[0].find('td') is None 
True 
>>> rows[0].find_all('th') 
[<th width="20%">Name</th>, <th>Meaning</th>, <th>Popular <br/>\nalternate spellings</th>] 

Es gibt eine andere solche Reihe, so dass Sie defensiv codieren müssen:

>>> rows[26] 
<tr><th width="20%">Name</th><th>Meaning</th><th>Popular <br/>\nalternate spellings</th></tr> 

Sie testen konnte nur, wenn es irgendwelche Elemente mit einer if Erklärung sind:

if row_datas: 
    print row_datas[0] 

-Code zu extrahieren alle Namen, Bedeutungen und alternative Schreibweisen ist so einfach wie:

for row in soup.select('table.contentTable tr'): 
    cells = row.find_all('td') 
    if not cells: 
     continue 
    name_link = cells[0].find('a') 
    name, link = name_link.get_text(strip=True), name_link.get('href') 
    meaning, alt = (cell.get_text(strip=True) for cell in cells[1:]) 
    print '{}: {} ({})'.format(name, meaning, alt) 
+0

Danke für das Aufzeigen des Fehlers. Es war wirklich dumm von mir, das übersehen zu haben. Und danke, dass du mir einen viel saubereren Code gegeben hast! – forcehandler

0

Sie erhalten diesen Fehler, weil Ihre Liste keine Elemente enthält, row.find_all("td") kann nichts finden, Sie müssen entweder Ihre HTML-Struktur überprüfen oder die select Methode verwenden.

select() Rückkehr alle Elemente über einen CSSS Wähler slected, es ist ziemlich mächtig, wird Ihr Code so ähnlich sein:

row_datas = soup.select("td") #Note that select() is method of a BeautifulSoup Object . 
    print row_datas 
    print row_datas[0] 
+0

'select()' scheint viel besser zu benutzen als die 'find()' Funktion. Danke für deine Antwort! – forcehandler

Verwandte Themen