Kódím.cz
1

Web scraping

Naučíte se jak ve vašich Python programech vytáhnout data z webových stránek.

Web scraping v Pythonu

Abychom mohli s obsahem webových stránek pracovat přímo v Pythonu, potřebujeme nainstalovat modul, který umí číst HTML značky a pomocí těchto značek v HTML souborech vyhledávat. Takových modulů pro jazyk Python existuje vícero. My použijeme balíček zvaný requests-html, který je určený přímo pro web scraping. Nainstalovat jej můžeme příkazem

pip3 install requests-html

Popř. na Windows

pip install requests-html

Abychom mohli v našem programu scrapovat, musíme nejdřív webovou stránku otevřít. Vzhledem k tomu, že obsah textového souboru už do proměnné načíst umíme, stačí tedy jen použít náš nový modul, aby si tento obsah přečetl a umožnil v něm vyhledávat.

Ve Visual Studiu ve složce s naší ukázkovou stránkou si vytvořte program scrape.py s tímto obsahem

from requests_html import HTML
with open('ukazka.html', encoding='utf-8') as soubor:
    obsah = soubor.read()
html = HTML(html=obsah)

Proměnná html nyní obsahuje naši HTML stránku ve formátu, který můžeme použít k vyhledávání.

HTML značky můžeme vyhledávat podle jména. Takto například najdeme všechny odstavce a vypíšeme jejich text každý na nový řádek.

for odstavec in html.find('p'):
    print(odstavec.text)

Velmi časté je také vyhledávání podle třídy (atribut class). Třídy se vyhledávají tak, že jejich název začneme tečkou.

html.find('.sekce1')

Snadno také můžeme přistupovat k atributům nalezených značek. Takto můžeme například najít adresy všech odkazů na naší stránce.

for odkaz in html.find('a'):
    print(odkaz.attrs['href'])

Složitější pravidla vyhledávání

Vyhledávací řetězce v metodě find() mohou být složitější, než jak jsme viděli doposud.

Můžeme vyhledávat podle více značek najednou. Například najít všechny nadpisy první i druhé úrovně.

html.find('h1, h2')

Můžeme vyhledávat podle atributů. Například najít všechny seznamy, kde atribut type je roven a.

html.find('ol[type="a"]')

Můžeme vyhledávat podle zanoření. Například najít všechny odstavce, které jsou uvnitř značky s třídou sekce1.

html.find('.sekce1 p')

Mezera ve vyhledávacím řetězci znamená libovolně hluboké zanoření. Pokud bychom chtěli pouze odstavce, které jsou přímým potomkem značky s třídou sekce1, použijeme symbol zobáčku.

html.find('.sekce1 > p')

Pokud tyto techniky zkombinujeme, můžeme například najít všechny položky ve všech seznamech, jejichž atribut type je roven a.

html.find('ol[type="a"] li')

Scraping přes internet

Zatím jsme scrapovali pouze stránku, kterou jsme měli uloženou na disku. Pomocí modulu requests-html můžeme však také snadno otevřít stránku přímo na internetu. Na adrese https://apps.kodim.cz/python-data/scrape najdete naši malou ukázkovou stránku z úvodu. Na adrese https://apps.kodim.cz/python-data/dhmo najdete také finální verzi stránky šířící poplach ohledně DHMO.

Načteme v Pythonu první z odkazů a stejně jako prve vypíšeme texty všech odstavců.

from requests_html import HTMLSession
session = HTMLSession()
stranka = session.get('https://apps.kodim.cz/python-data/scrape')
for odstavec in stranka.html.find('p'):
    print(odstavec.text)

Dále můžeme postupovat úplně stejně jako když jsme zpracovávali stránky z disku. Pokud chcete vidět celý stažený zdrojový kód stránky jako text, napište

print(stranka.html.html)

Cvičení: Scraping

Web scraping vs JavaScript

Web scraping je velmi mocná technika. Její úspěšnost však závisí na tom, jakým způsobem jsou webové stránky napsány. Pokud jsou napsány prasácky a nekonzistentně, tak si web scrapingem můžeme snadno způsobit velký bolehlav.

Jeden z velkých problémů pro web scraping však představují stránky, které jsou vytvořené celé v JavaScriptu. Velkým trendem v dnešní době je nepsat HTML kód stránky přímo, jako jsme to viděli výše. Místo toho se použije jazyk JavaScript, který kód stránky sám vygeneruje. Tím může být stránka mnohem flexibilnější a interaktivnější, což je hezké pro uživatele. Pro nás to však znamená, že když stránku stahujeme v Pythonu, neobdržíme značky HTML, ale JavaScriptový program, který nejdříve musíme v Pythonu spustit a nechat si výsledné HTML vygenerovat.

Podívejte se například na tuto stránku, která je psána přesně tímto způsobem. Pokud chceme takovou stránku scrapovat, musíme použít takovýto kód.

from requests_html import HTMLSession
session = HTMLSession()
stranka = session.get('https://react-shopping-cart-67954.firebaseapp.com/')
stranka.html.render(sleep=5)

Doporučené úložky na doma

Čtení na doma

Webscraping je velmi široká oblast a těžko se člověk do jejích tajů dostane během jedné lekce. Obzvláště u komplikovanějších stránek je často nutné zkoušet různé techniky a přístupy, umět si poradit v různých situacích, nenechat se snadno odradit ošklivě napsaným HTML kódem a vůbec být mazaný jako liška.