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:

Příklady:

  • Příkaz 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)
  • Pokročilejší filtrování:
    1. Vypište všechny složky pod /etc, které mají alespoň trojpísmenný název
    2. Vypište všechny symbolické linky v /etc bez sestupování do podsložek (tedy už ne symlinky v /etc/neco/...)
    3. V adresáři /etc najděte soubory, které jsou novější než /etc/passwd
    4. Vypište všechny normální soubory v /etc, které nevlastí root
    5. Spočítejte velikost všech souborů v /etc s příponou .sh
    6. 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

    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="...", zkonstruujte 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é)


    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