Wyciąganie danych ze stron - lxml
25.11.2012 15:10
Nie raz zdarza się nam że potrzebujemy jakiś danych z jakiś stron. Co jednak gdy na stronie jest dużo różnych elementów nam całkowicie niepotrzebnych lub potrzebujemy pobrać z wielu podstron ? Z pomocą przychodzi nam biblioteka lxml
1. lmxl - Co to takiego?
Jest to biblioteka dla języka Python która pozwala nam przetwarzać dane z plików XML i HTML. Można znaleźć ją w standardowych repozytoriach dystrybucji z rodziny Linux lub pobrać z strony projektu
2. Jak zacząć zabawę?
Pierwszym krokiem trzeba będzie zaimportować do naszego skryptu tą bibliotekę a robimy to następująco
import lxml.html
Teraz pozostaje nam wybrać źródło którym mogą być strony na dysku bądź gdzieś zdalnej lokacji korzystając np z biblioteki urllib2 lub podobnej
3. Co dalej?
Aby można było przetwarzać dane za pomocą lxml trzeba sprowadzić je do postaci stringa a następnie użyć:
szkielet = lxml.html.fromstring(dane).
Gdzie zmienna "dane" oznaczają nazwę zmiennej przechowującą surową strukturę pliku
Dla przykładu teraz jeśli chcemy pobrać nazwy i linki z wszystkich tagów na portalu
for element in szkielet.cssselect('a'): print element.text # Zwraca zawartość każdego tagu print element.attrib['href'] # zwraca atrybut każdego tagu gdzie w nawiasach musi być nazwa tego atrybutu
ale co jeśli chcemy pobrać tylko jeden?
Wtedy stosujemy zamiast pętli takie coś:
element = szkielet.cssselect('a')[0] print element.text print element.attrib['href']
4. Wyciąganie elementów z rozbudowanych struktur
W poprzednich akapitach mogliście zobaczyć jak się pobiera wszystkie linki ze strony. Co jeśli jednak potrzebujemy tylko tego konkretnego ?
Na warsztat weźmiemy taki fragment pliku HTML:
<div> <span> jakiś tekst</span> <a href="http://dobreprogramy.p">Nasz portal</a> </div> <div> <span> jakiś tekst</span> <div id='zly'> <a href="http://zleprogramy.p">Konkurencyjny portal</a> </div> </div>
Naszym zadaniem jest pobranie linki z tagu "div" z identyfikatorem "zly"
element = szkielet.cssselect('div#zly a')[0] print element.attrib['href']
Tu wprowadzamy w cssselect "div#zly" gdyż zły jest identyfikatorem ale jeśli w miejsce id było by class wtedy stosujemy "div.zly
Pamiętajmy aby ostrożnie stosować poruszanie się po dynamicznych stronach gdyż bez zabezpieczonego skryptu przed wykryciem wyjątku w razie braku jakiegokolwiek tagu może dojść do awarii skryptu a co za tym idzie nieprawidłowego działania i wprowadzenia danych
5. Wyciąganie tytułów wpisów z blogu
import urllib2 import lxml.html dane = urllib2.urlopen('http://www.dobreprogramy.pl/sylwek3100').read() #pobieramy dane z mojego bloga szkielet = lxml.html.fromstring(dane) #ładujemy je do szkieletu for artykul in szkielet.cssselect('article'): #inicjujemy pętle pobierającą wszystkie tagi <a rel="nofollow"rticle> tytul = artykul.cssselect('header a')[0] #wyciągamy linka z wewnątrz tagu <header> print tytul.text #wyswietlamy zawartość linka
Dziękuje wszystkim za uwagę.