Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Wyciąganie danych ze stron - BeautifulSoup

W poprzednim wpisie zajęliśmy się wyciąganiem danych ze stron HTML za pomocą biblioteki dla Pythona o nazwie lxml. Dzisiaj jednak zajmiemy się inną biblioteką a mianowicie BeautifulSoup.

1. Skąd wziąć tę zupę?

Naszym pierwszym krokiem który należy wykonać jest zdobycie jej. Możemy ją pobrać za pomocą wielu repozytoriów w systemach Liniksopochodnych oraz za pomocą strony projektu.

2. Zupa jako jedno z dan?

Aby dodać Beautiful Soup do naszego projektu należy zaimportować bibliotekęimport BeautifulSoup

Następnym elementem jest wybrać źródło. Ja standardowo wybrałem stronę pobraną za pomocą urllib2 a później zainicjować dla przykładu używając:zupa = BeautifulSoup.BeautifulSoup(dane)gdzie zmienna zupa oznacza kontener którym się będziemy posługiwać dalej a dane oznaczają zmienną string z zawartością strony.

3. Własne danie na bazie zupy

Przejdźmy teraz do praktycznej części w której zajmiemy się kilkoma metodami wyciągania danych za pomocą BeautifulSoup.

3.1 Pobranie wszystkich tagów

To zadanie wykonuje funkcja : BeautifulSoup.findAll( tag, # nazwa poszukiwanego taga atrybuty = {} #słownik atrybutów ) Zwraca ona listę struktur zawartych w danym tagu
Dla przykładu pobierzemy strukture wewnątrz wszystkich tagów <div>:

zupa = BeautifulSoup.BeautifulSoup(dane) #inicjujemy użycie biblioteki elementy = zupa.findAll('div') # wyszukujemy po określonym tagu for element in elementy: print element #wyświetlamy strukture każdego diva

3.2 Pobranie jednego taga

To zadanie wykonuje funkcja : BeautifulSoup.find( tag, # nazwa poszukiwanego taga atrybuty = {} #słownik atrybutów ) Zwraca ona zawartość jednego taga

Aby wyświetlić zawartość taga bez żadnych struktur (tzw czysty tekst) musimy wyodrębnić za pomocą contents[0]

Co jeśli jednak sama nazwa taga nam nie wystarczy do wyszukiwania odpowiedniego elementu ze struktury ?

Wtedy możemy zastosować drugi atrybut funkcji find i findAll
w formacie:

{pierwszyatrybut:wartosc,drugiatrybug:wartosc}

4. Propozycja podania

Aby trochę pokazać na przykładzie jak operować tą biblioteką bierzemy na warsztat skrypt podobny do wczorajszego jednak go trochę ulepszymy:

import urllib2 import BeautifulSoup def blog(uzytkownik): dane = urllib2.urlopen('http://www.dobreprogramy.pl/'+uzytkownik).read() zupa = BeautifulSoup.BeautifulSoup(dane) try: artykuly = zupa.findAll('article') for element in artykuly: tytul = element.find('a') czas = element.find('time') print tytul.contents[0] print czas.contents[0] except AttributeError: print 'Ten uzytkownik nie prowadzi bloga' blog('sylwek3100') blog('ulth')

Zadanie skryptu to pobieranie tytułów i czasu elementów na blogu. Jednak w tym wypadku zabezpieczyliśmy skrypt przed użytkownikiem który może nie posiadać jeszcze żadnego wpisu wychwytując wyjątek AttributeError i dając komunikat w razie takowego wykrycia. Można zobaczyć to na przykładzie 2 użytkowników.
Co jeśli jednak to nam nie wystarczy i będziemy chcieli pobrać jeszcze ilość komentarzy pod danym wpisem na blogu ?

Wykorzystujemy drugi parametr funkcji find i nim przekazujemy atrybuty danego taga w tym wypadku to wygląda tak:

komentarzy = element.find('span',{'class':'text-h0'}) print komentarzy.contents[0]

Warto jednak zaznaczyć że dalej to musimy przechowywać w tej samej pętli co poprzednie elementy (tytuł, czas).

Jeśli masz jakieś wątpliwości daj znać w komentarzu.

Dziękuje wszystkim czytającym za cierpliwość i uwagę 

programowanie

Komentarze

0 nowych
Demagog   4 #1 26.11.2012 18:58

Miły, zgrabnie napisany, dobrze podzielony wpisik.
Ufff, no i bez wszystkoniemającego Windows 8.
Masz + i to wielkiego ode mnie.

msnet   18 #2 27.11.2012 17:06

Windows 8 nie ma wszystkiego i nie wszystko potrafi - na przykład nie daje rano śniadania, z zupelnie nieznanych mi powodów. W linuxie też tak jest?

A wpis ciekawy, bez zbędnego wodolejstwa. krótko i na temat.

iluzion   5 #3 28.11.2012 17:01

BeautifulSoup to absolutny "must have". Ps Używasz starej wersji. Proponuję dać `pip install beautifulsoup4` i później `import bs4`.

sylwek3100   3 #4 28.11.2012 22:33

@iluzion Możliwe. Ważne że działa i chciałem pokazać O co mniej więcej chodzi.

kwpolska   5 #5 30.11.2012 20:14

@sylwek3100 może i działa, ale starych wersji oprogramowania nie powinno się używać, a tym bardziej uczyć używać. BS jest znacznie wygodniejszy niż lxml, a obsługuje też jego parser, jak ładnie poprosisz (a powinieneś prosić, bo w py3k lxml standalone działa źle.)

sylwek3100   3 #6 01.12.2012 21:11

@kwpolska BS jest wygodniejszy ale nie jest szybszy od lxml a że w 3.x działa źle to niestety możemy częściowo zawdzięczać twórcom języka którym się coś lekko w głowach pomieszało