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
- Parsování argumentů – pomocí příkazu
getopts
- Formátovací string:
ab:c
definuje přepínačea
,b
ac
, kdeb
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
- Formátovací string:
- 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
- Hodí se použít dočasný soubor získaný pomocá
- 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
- Přepínač
- Získání odkazů – pomocí
sed
u- Odkazy jsou ve tvaru
href="..."
, zkonstruujeme si pro ně regex - Přepínač
p
na konci sedového příkazus
ubstitute způsobí výpis nahrazené části
sed -n 's/.*href="\([^"]*\)".*/\1/p' "$t"
- Odkazy jsou ve tvaru
- 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