Použití parseru lxml pro HTML

PythonPřestože jsem původně nechtěl, musím nyní programovat v jazyce Python. Sice jsem naučený perlista, ale Python se nezdá zas tak hrozný. Dnes jsem začal s průzkumem možností vytváření ElementTrees z HTML kódu. Jako parser jsem zvolil modul lxml.

Pythonovský modul lxml jsem zvolil z důvodu jednoduchosti použití a dobrých výsledků rychlostního benchmarku, který jsem našel na stránkách Iana Bickinga. Pro své účely používám speciálnější verzi lxml.html pro parsování HTML, ale v uvedeném postupu se mění pouze jméno modulu. Zájemcům o další funkce modulu lxml jistě neuniknou odkazy na konci článku.

Směle se vydejme vstříc malému základu použití modulu. Nejprve je potřeba jej importovat do programu.

import lxml.html as lh

Protože chci parsovat HTML stránky, musím si nějaké obsarat, a proto by byl vhodný modul umožňující HTTP requesty. Opener klasického modulu urllib2 tuto práci vykoná bezvadně.

import urllib2

Hned po inicializaci openeru, je možno stahovat a parsovat HTML stránky.

opener = urllib2.build_opener() # incializace
opener.addheaders = [('User-agent', 'Fanda\'s bot')] # nastavení openeru
page = opener.open("http://www.example.net") # stažení stránky
tree = lh.parse(page) # vytvoření ElementTree z HTML

lh.parse vrátilo standardní ElementTree, se stejným rozhraním jako kdybych pro jeho získání použil HTMLparser. Základy práce s ElementTree tvoří pár metod, jejichž referenční manuál můžete najít mezi odkazy pod článkem.

Já v ukázce načrtnu získání a zpracování textových odkazů na stránce. Pole anchorů nechám projít cyklem for, který v nich bude vyhledávat regulárním výrazem a všem relativním odkazům pridá domovskou adresu, takže budou absolutní.

import re
links = self._current_tree.findall('html/body/a')
final = []
regul = re.compile(r'REGEXP')
for link in links:
    link.make_links_absolute(base)
    # všechny atrubuty a text dohromady
    texts = " ".join(link.values()) + " " + link.text_content()
    if regul.search(texts): # regul matches
    final.append(link.get('href')) # získnání URL
uniq = list(set(final)) # vykoná uniq

Speciálně modul lxml.html totiž nabízí funkce
make_links_absolute(base) pro tvorbu absolutních odkazů,
iterlinks() pro hledání odkazů uvnitř atributů,
resolve_base_href() pro zajistění vhodné domovské stránky a
rewrite_links(link_replace_function) pro pomoc při přepisování odkazů.

Jelikož funkce make_links_absolute volitelně volá také funkci resolve_base_href, což je ve výchozím nastavení zapnuto, není potřeba ji explicitně volat.