2009-10-16 13 views
5

I jestem nowy lxml, zupełnie nowy, python i nie mógł znaleźć rozwiązanie, co następuje:python, lxml i XPath - html tabeli parsowanie

muszę zaimportować kilka stolików z 3 kolumnami i niezdefiniowane liczba wierszy zaczynających się od wiersza 3.

Gdy druga kolumna dowolnego wiersza jest pusta, ten wiersz jest odrzucany, a przetwarzanie tabeli jest przerywane.

Poniższy kod wypisuje dane grzywny stołu (ale jestem w stanie ponownie wykorzystać dane potem):

from lxml.html import parse 

def process_row(row): 
    for cell in row.xpath('./td'): 
     print cell.text_content() 
     yield cell.text_content() 

def process_table(table): 
    return [process_row(row) for row in table.xpath('./tr')] 

doc = parse(url).getroot() 
tbl = doc.xpath("/html//table[2]")[0] 
data = process_table(tbl) 

ten drukuje tylko pierwszą kolumnę :(

for i in data: 
    print i.next() 

następującym tylko zaimportować trzeci wiersz, a nie kolejny następujący po nim:

Każdy wie, jakie jest wymyślne rozwiązanie, aby uzyskać wszystkie dane z wiersza 3 do tbl i skopiuj go do tablicy, aby można było przetworzyć go w moduł bez zależności lxml?

Dzięki z góry za pomoc Alex

+0

Czy możesz wkleić dokument źródłowy (lub jego część) i oczekiwany wynik? Nie jestem ekspertem w python, ale jestem dobry w xpath i myślę, że mogę ci pomóc. – prostynick

+0

Dokument źródłowy jest dostępny tutaj (tylko od 06:00 do 22:00): http://tinyurl.com/yj4corh – user191131

+0

oczekiwany wynik: [['Premier', '05', 'name1'], [u'Deuxi \ xe8me ',' 13 ',' name2 ']] – user191131

Odpowiedz

0

Trzeba używać pętlę dostęp do danych rzędu, podobnie jak to:

for row in data: 
    for col in row: 
     print col 

Wywołanie next() raz jak ty będzie miał dostęp tylko pierwszy element, dlatego widzisz jedną kolumnę.

Należy pamiętać, że ze względu na charakter generatorów, można uzyskać do nich dostęp tylko raz. Jeśli zmienisz połączenie process_row(row) na list(process_row(row)), generator zostanie przekonwertowany na listę, która może być ponownie użyta.

Aktualizacja: Jeśli zajdzie potrzeba tylko 3 rzędzie i dalej, użyj data[2:]

+0

Dzięki, zagnieżdżona pętla i dodanie wywołania list() rzeczywiście poradziły sobie. Ale nadal nie działa z drugą xpath, która jest tym, czego potrzebuję (chyba) – user191131

+0

Nie jest dla mnie jasne, dlaczego potrzebujesz drugiej xpath, zobacz aktualizację mojej odpowiedzi. – interjay

+0

Potrzebuję całej zawartości tabeli począwszy od wiersza 3, a druga ścieżka xpath zwraca tylko jeden wiersz. Oczywiście zrobiłem to, co zasugerowałeś w swojej aktualizacji, ale jestem ciekawy, co jest nie tak z drugim xpath, ponieważ spowodowałoby to, że mój kod na następne dni byłby czystszy. – user191131

2

Jest to generator:

def process_row(row): 
    for cell in row.xpath('./td'): 
     print cell.text_content() 
     yield cell.text_content() 

Dzwonisz go tak, jakbyś myślał, że zwraca listę. Tak nie jest. Istnieją konteksty, w których zachowuje się jak listy:

print [r for r in process_row(row)] 

ale to tylko dlatego, generator oraz wykaz zarówno wystawiać ten sam interfejs do for pętli. Używanie go w kontekście, w którym robi się ocenianym tylko jeden raz, np .:

return [process_row(row) for row in table.xpath('./tr')] 

po prostu wywołuje nową instancję generatora raz dla każdej nowej wartości row, zwracając pierwszy rezultat dało.

To jest twój pierwszy problem. Twój drugi jest, że czekasz:

tbl = doc.xpath("//body/table[2]//tr[position()>2]")[0] 

dać trzeci i wszystkie kolejne wiersze, a to ustawienie tylko tbl do trzeciego rzędu. Cóż, wywołanie xpathjest zwrócenie trzeciego i wszystkich kolejnych wierszy. To jest [0] na końcu, który cię denerwuje.

+0

Dziękuję za twoją odpowiedź. Ale usunięcie [0] na końcu xpath podnosi wyjątek: AttributeError: obiekt 'list' nie ma atrybutu 'xpath' – user191131

+0

Nie sądzę, że samo usunięcie '[0]' z końca tej instrukcji spowodowało, że błąd. Zmieniłeś coś innego lub błąd zostanie zgłoszony później. –

+0

Wybaczcie tej biednej duszy, muszę przyznać, że moje umiejętności związane z Pythonem są bardzo prawdopodobne ... Oto fragment kodu, który mnie wkurza: http://pastebin.com/m522b6970 – user191131