Desáté cvičení – Web crawler aneb rekurzivní stahovač

Zadání

Toto cviko bylo věnováno celé jednomu většímu příkladu – napsání rekurzivního stahovače webových stránek.

Úkol: Napište skript, který dostane URL a stáhne z ní a z odkazovaných stránek všechny emailové adresy. Měl by umět nastavit hloubku rekurze pomocí parametru -r <číslo>, defaultně 10.

Základní části

  1. Parsování argumentů – pomocí příkazu getopts
    • Formátovací string: ab:c definuje přepínače a, b a c, kde b bere parametr
    • getopts vrací postupně všechny parametry (název v definované proměnné, hodnotu v $OPTARG a číslo parametru v $OPTIND)
    • Pro zpracování jednotlivých parametrů se hodí použít case <proměnná> in, klauzule *) je default
    
    while getopts r: opt; do
    	case $opt in
    		r) r=$OPTARG;;
    		*) echo "Usage: $0 [-r DEEP]";;
    	esac
    done
    
  2. Stažení jedné stránky – pomocí příkazu wget s nastaveným výstupem přepínačem -O
    • Hodí se použít dočasný soubor získaný pomocá mktempt
    
    t=$(mktemp)
    wget -O "$t" "$url" 2>/dev/null
    
  3. Získání emailových adres – vhodným použitím regulárních výrazů a příkazu grep
    • Přepínač -E zapíná extended regexy, přepínač -o způsobuje výpis pouze matchnutých částí
    
    grep -Eo "[a-zA-Z0-9+.-]+@[a-zA-Z0-9+.-]+" < "$t" >> mailove_adresy.txt
    
  4. Získání odkazů – pomocí sedu
    • Odkazy jsou ve tvaru href="...", zkonstruujeme si pro ně regex
    • Přepínač p na konci sedového příkazu substitute způsobí výpis nahrazené části
    
    sed -n 's/.*href="\([^"]*\)".*/\1/p' "$t"
    
  5. Rekurzivní dotazy – nestihli jsme dodělat. Zbývá:
    • Zajistit, abychom stejný odkaz stahovali jenom jednou
    • Omezit se jen na doménu danou původním odkazem (nebylo v původním zadání, ale je velmi užitečné)

Celý program:


r=100 # default
while getopts r: opt; do
	case $opt in
		r) r=$OPTARG;;
		*) echo "Usage: $0 [-r DEEP]";;
	esac
done
shift $(($OPTIND - 1))

url="$1"
t=$(mktemp)

wget -O "$t" "$url" 2>/dev/null

grep -Eo "[a-zA-Z0-9+.-]+@[a-zA-Z0-9+.-]+" < "$t" >> mailove_adresy.txt

sed -n 's/.*href="\([^"]*\)".*/\1/p' "$t"

# Zbývá dodělat rekurzi