KursyWalut czyli dalsza przygoda z web scrapingiem

Obiecałem, że napiszę jeszcze coś o web scrapingu. Popełniłem prosty program w Pythonie do pozyskiwania aktualnych kursów walut ze strony http://finanse.wp.pl/waluty.html i ich przeliczania. Kod dostępny na licencji GNU GPL v2. Zamiast zbędnego rozpisywania się, zapraszam do forkowania:

https://github.com/bartgee/KursyWalut

więcej info: http://grzybicki.pl/moje-programy/https://github.com/bartgee/KursyWalut/blob/master/README.md

Web scraping czyli „skrobanie WWW”

Web scraping, czyli „skrobanie WWW”, lub bardziej formalnie ekstrakcja danych ze stron WWW, to programowa technika ekstrakcji informacji ze stron WWW. Takie oprogramowanie zazwyczaj symuluje eksplorację stron WWW jaką wykonuje człowiek przeglądając i analizując strony webowe.

Web scraping jest ściśle związany z indeksowaniem WWW, które polega na indeksowaniu informacji zawartej na stronach WWW za pomocą bota lub web crawlera. Technika ta została zaadoptowana w większości silników wyszukujących. W przeciwieństwie do nich, web scraping skupia się bardziej na przekształceniu niestrukturalnych danych ze stron WWW, zwykle w formacie HTML, do postaci danych strukturalnych, które można łatwo gromadzić i analizować w centralnej lokalnej bazie danych lub arkuszu kalkulacyjnym. (*)

To tyle jeśli chodzi o nakreślenie tematu. Zainteresowałem? Jeśli tak, to zachęcam do dalszego czytania. Poniżej zamieszczam prosty kod pythonowy, który ma pokazać, jak można wykorzystać web scraping do własnych celów. Program wczytuje dane ze strony http://www.linuxtoday.com i dodaje je do listy dictów (lub słowników – jeśli ktoś woli). Mając już dane w postaci strukturalnej można z nimi zrobić co się chce. Dodatkowo, program zapisuje wyświetlone dane do pliku linuxtoday.txt. Jako ćwiczenie pozostawiam dopisanie funkcji zapisującej pobrane dane do bazy np. SQLite3 (lub innej ulubionej).

Jak tworzyć odpowiednie ścieżki XPath?

Przeglądając stronę WWW np. w Chrome, najeżdżasz kursorem myszy nad interesującym Cię elementem i klikasz prawy przycisk myszy. Pojawia się menu kontekstowe, klikasz „zbadaj element”. W panelu „Inspektor” w dolnej części przeglądarki, klikasz na strzałce w linii, która została podświetlona i jeśli widzisz element, który Cię interesuje, klikasz prawym przyciskiem myszy na nim. Pojawia się kolejne menu kontekstowe, z którego wybierasz „Copy XPath”. Pewnie brzmi to dość zawile, ale po kilku próbach, stanie się prostą czynnością. :-)

BTW – w tym roku byłem na PyConPL i niestety za późno chciałem się zapisać na warsztat o web scrapingu. Temat mnie jednak zainteresował i zmobilizowałem się do zbadania tego tematu. Na pewno jeszcze coś o tym napiszę.

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# author Bart Grzybicki <bgrzybicki@gmail.com>
 
from lxml import html
import requests
 
OUT_FILE = u'linuxtoday.txt'
 
def main():
    page = requests.get('http://www.linuxtoday.com')
    tree = html.fromstring(page.text)
    lt_list = []
    index = 1
    while True:
        lt_dict = {}
        title = tree.xpath('//*[@id="container"]/table[3]/tbody/tr/td[2]/div[3]/div[{}]/a/strong/text()'.format(index))
        post_date = tree.xpath('//*[@id="container"]/table[3]/tbody/tr/td[2]/div[3]/div[{}]/span/text()[1]'.format(index))
        link = tree.xpath('//*[@id="container"]/table[3]/tbody/tr/td[2]/div[3]/div[{}]/a/@href'.format(index))
        desc = tree.xpath('//*[@id="container"]/table[3]/tbody/tr/td[2]/div[3]/div[{}]/p/span/text()'.format(index))
        if desc == []:
            desc = tree.xpath('//*[@id="container"]/table[3]/tbody/tr/td[2]/div[3]/div[{}]/p/text()'.format(index))
        else:
            desc_bckp = desc
        if title == []:
            break
        else:
            idx = post_date[0].index('\n')
            post_date[0] = post_date[0][:idx]
            post_date[0] = post_date[0].replace(' (', '')
            post_date[0] = post_date[0].replace(')', '')
            lt_dict['title'] = title[0]
            lt_dict['date'] = post_date[0]
            lt_dict['link'] = link[0]
            try:
                lt_dict['description'] = desc[0]
            except Exception:
                lt_dict['description'] = ''
            lt_list.append(lt_dict)
            index += 1
    out_file = open(OUT_FILE, 'w')
    for x in lt_list:
        final_out = (x['title'] + '\n' + x['date'] + '\n' + x['link'] + '\n' + x['description'] + '\n')
        final_utf8 = final_out.encode('utf-8')
        print(final_utf8)
        print(u'Saving data to ' + OUT_FILE + u'...')
        out_file.write(final_utf8)
        out_file.write(u'\n')
    out_file.close()
    print(u'Done.')
 
if __name__ == '__main__':
   main()

Dla ułatwienia zamieściłem powyższy kod na GitHubie w postaci gista, którego możesz sforkować i pobawić się kodem:

https://gist.github.com/bartgee/4eb1838a8fb9d3f6c340

* – źródło ze strony: http://en.wikipedia.org/wiki/Web_scraping