2009-03-02 21 views
16

Jestem nowym użytkownikiem Pythona i potrzebuję pomocy w zakresie składni do znajdowania i iterowania za pomocą znaczników html przy użyciu lxml. Oto przypadki użycia, z którymi mam do czynienia:Potrzebujesz pomocy dla składni lxml w pythonie dla html

Plik HTML jest dość dobrze uformowany (ale nie doskonały). Ma wiele tabel na ekranie, z których jedna zawiera zestaw wyników wyszukiwania, a druga dla nagłówka i stopki. Każdy wiersz wyników zawiera link do szczegółów wyniku wyszukiwania.

  1. Muszę znaleźć środkowy tabelę z wierszy wyników wyszukiwania (ten udało mi się dowiedzieć):

    self.mySearchTables = self.mySearchTree.findall(".//table") 
        self.myResultRows = self.mySearchTables[1].findall(".//tr") 
    
  2. Muszę znaleźć linki zawarte w tej tabeli (w tym gdzie utknęłam):

    for searchRow in self.myResultRows: 
         searchLink = patentRow.findall(".//a") 
    

    Wygląda na to, że nie znajdują się w nich elementy linków.

  3. Potrzebuję zwykłego tekstu linku. Wyobrażam sobie, że byłoby to coś w rodzaju searchLink.text, gdybym rzeczywiście dostał elementy linków.

Wreszcie, w faktycznym odnośniku API dla lxml, nie byłem w stanie znaleźć informacji na temat wywołania find i findall. Zbieram je z fragmentów kodu znalezionych w google. Czy brakuje mi czegoś, jak skutecznie znaleźć i iterować tagi HTML za pomocą lxml?

Odpowiedz

27

Po pierwsze, jeśli chodzi o parsowanie kodu HTML: jeśli zastosujesz się do zaleceń zweiterlinde i S.Lott, użyj przynajmniej wersji beautifulsoup included with lxml. W ten sposób będziesz również czerpał korzyści z dobrego interfejsu xpath lub selektora css.

Jednak ja osobiście wolę Iana Bickinga od HTML parser included in lxml.

Po drugie, .find() i .findall() pochodzą z lxml próbując być kompatybilne z ElementTree, a te dwie metody są opisane w XPath Support in ElementTree.

Te dwie funkcje są dość łatwe w użyciu, ale mają bardzo ograniczony XPath. Zaleca się użycie pełnego lxml xpath() method lub, jeśli znasz już CSS, używając cssselect() method.

Oto kilka przykładów, z napisu HTML analizowany tak:

from lxml.html import fromstring 
mySearchTree = fromstring(your_input_string) 

użyciu klasy selektor CSS program będzie mniej więcej wyglądać tak:

# Find all 'a' elements inside 'tr' table rows with css selector 
for a in mySearchTree.cssselect('tr a'): 
    print 'found "%s" link to href "%s"' % (a.text, a.get('href')) 

Ekwiwalent za pomocą metody xpath będzie:

# Find all 'a' elements inside 'tr' table rows with xpath 
for a in mySearchTree.xpath('.//tr/*/a'): 
    print 'found "%s" link to href "%s"' % (a.text, a.get('href')) 
+0

Yay! Dokładnie to, czego potrzebowałem. Zinterpretowałem cssselect, aby rzeczywiście wymagało, aby elementy miały zadeklarowaną klasę css. Zagnieżdżona logika wyszukiwania jest właśnie tym, czego potrzebowałem! Dziękuję Van Gale! –

+0

Ta strona zaleca używanie iterchildren i iterdescendants z opcją tagu. http://www.ibm.com/developerworks/xml/library/x-hiperfparse/#N10239 – endolith

+1

Świetna odpowiedź, ale jako drobny spór - dlaczego '.// tr/*/a' zamiast' .// tr // a'? Ten pierwszy nie znalazłby nic z dodatkowym tagiem interweniującym, tj. '..' –

5

Czy istnieje powód, dla którego nie używasz Beautiful Soup dla tego projektu? Sprawi, że radzenie sobie z niedoskonale uformowanymi dokumentami będzie znacznie łatwiejsze.

+0

+1: lxml jest dla xml. Piękna Zupa jest dla HTML. –

+2

Zacząłem od pięknej zupy, ale nie miałem szczęścia. W moim pytaniu wspomniałem, że mój doktor jest dość dobrze uformowany, ale brakuje mu końcowego bloku ciała.Po prostu upuszcza całą zawartość, gdy ją przeciągnę do parsera. Stąd lxml. Również http://tinyurl.com/37u9gu wskazał lepsze mem mgmt z lxml –

+7

Użyłem na początku BeautifulSoup, ale nie obsługuje złego HTML, jak również twierdzi. Nie obsługuje także elementów z wieloma klasami itp. Lxml.html jest lepszy we wszystkim, co z nim zrobiłem. – endolith

Powiązane problemy