Jedenácté cvičení – Web crawler aneb rekurzivní stahovač
Toto cviko bylo věnováno z části dodělávání chybějících věcí ze shellu a pak hlavně jednomu většímu příkladu – napsání rekurzivního stahovače webových stránek.
Příkazy a plán:
- Hledání pomocí
find
a jeho přepínače:-name '*.txt'
-size [+-]...
- …
xargs
getopts
acase
wget
Příklady:
find
hledá soubory (a složky) podle daných parametrů v zadaném umístění a provede s nimi akci (defaultní akce je vypsat jejich název)find /cesta -name "*.txt"
– najde ve složce (a podsložkách)/cesta
všechny soubory s příponou.txt
- Filtrování:
-user
,-uid
,-group
, … - Akce: print (default), delete, exec (dva druhy)
- Vypište všechny složky pod
/etc
, které mají alespoň trojpísmenný název - Vypište všechny symbolické linky v
/etc
bez sestupování do podsložek (tedy už ne symlinky v/etc/neco/...
) - V adresáři
/etc
najděte soubory, které jsou novější než/etc/passwd
- Vypište všechny normální soubory v
/etc
, které nevlastí root
- Spočítejte velikost všech souborů v
/etc
s příponou.sh
- Vypište všechny normální soubory v
/etc
, které nevlastí root a pro každý z nich vypiště dlouhé informace pomocíls -l
Velký úkol
Ú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="..."
, zkonstruujte 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é)
Základ programu:
(použitelné jako základ navazujícího úkolu)
r=10 # default
while getopts r: opt; do
case $opt in
r) r=$OPTARG;;
*) echo "Usage: $0 [-r DEEP]";;
esac
done
# Posuneme se o počet parametrů naparsovaných getopts (-1 kvůli +/-1 chybám)
shift $(($OPTIND - 1))
# Stažení jedné stránky
url="$1"
t=$(mktemp)
wget -O "$t" "$url" 2>/dev/null
# Vygrepování emailových adres
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 a další věci viz úkol v submitteru