Polecenie powłoki lub seria poleceń podobnych do akcji Automatora „Pobierz adresy URL linków ze stron internetowych”

1

Mam długą listę adresów URL. Na każdej z tych stron znajdują się linki, które muszę wyodrębnić. Akcja Automatora Pobierz adresy URL linków ze stron internetowych jest bardzo przydatną akcją dla tego zadania. Niestety sam Automator nie radzi sobie dobrze z dużymi obciążeniami i bardzo często ulega awarii lub zawiesza się w nieskończoność. Jak mogę to zrobić za pomocą Bash za pośrednictwem aplikacji terminalowej Mac OS X?

Edytuj - jest to bieżący skrypt w obecnej postaci.

#!/bin/bash

echo "Enter up to 3 words"
read -p "" v1 v2 v3 

web="$HOME/web.txt"
tmp="$HOME/tmp.txt"
err="$HOME/err.txt"
fin="$HOME/fin.txt"
arc="$HOME/arc.txt"

n="$(awk 'END {print NR}' "$web")"
echo "Processing $n URLs..."

grep 'http' "$web" | \
while read -r url; do
    lynx -nonumbers -hiddenlinks=merge -dump -listonly "$url" 2>>"$err" | awk '!a[$0]++' >> "$tmp"
    sleep 1
    n=$((n-1))
    [[ $n -gt 0 ]] &&  echo "$n URLs left to process..." || echo "Processing Completed!"
done

grep -e "$v1" -e "$v2" -e "$v3" "$tmp" | sort -u | cat > "$fin" 
cat "$fin" >> "$arc"

for r in "Results This Session"; do echo "$(cat "$fin" | wc -l)" "$r"; done
for a in "URL's Archived"; do echo "$(cat "$arc" | wc -l)" "$a"; done

Dodałem read -pna początku skryptu. Czy istnieją ograniczenia dotyczące liczby zmiennych, których można użyć w ten sposób? Z powodzeniem wykorzystałem do 9 w testowaniu. Czy istnieje bardziej praktyczny sposób na napisanie tego? Próbowałem, read -p "" {v1..v9}co nie zadziałało. Na końcu dodałem kilka forpętli, aby wskazać, ile danych zostało przetworzonych.

Bieżące problemy

  • czasami pojawia się błąd

    sort: string comparison failed: Illegal byte sequence
    sort: Set LC_ALL='C' to work around the problem.
    

    jednak po dodaniu LS_ALL=Cdo skryptu nie wydaje się to poprawne.

I0_ol
źródło
Mam już zainstalowany rysia za pośrednictwem Homebrew.
I0_ol
W porządku. IMO pisze skrypt bash za pomocą rysia, aby uzyskać linki z listy adresów URL. Z docelowymi adresami URL w pliku tekstowym, po jednym w wierszu, plik może być odczytywany w jednym wierszu i przetwarzany w pętli z zegarem, aby nie hamować serwera zbyt szybko, jeśli adresy URL wskazują tę samą domenę i lub po prostu odpowiednio tempo. Wszystkie dane wyjściowe są umieszczane w innym pliku do filtrowania w razie potrzeby, aby przejść do listy pożądanych adresów URL. Potrzebujesz pomocy ze skryptem?
user3439894
Tak, byłoby świetnie, gdybyś mógł. Zaczynam się uczyć bash, ale jestem bardzo nowy. Mam adresy URL w zwykłym pliku tekstowym po jednym w wierszu. Po prostu nie jestem pewien, dokąd się udać.
I0_ol

Odpowiedzi:

1

Oto skrypt na początek:

#!/bin/bash

urls="/path/to/Input_URLs_List.txt"
output="/path/to/Output_Link_URLs.txt"

n="$(awk 'END {print NR}' "$urls")"
echo "Processing $n URLs..."

cat "$urls" | \
while read url; do
    lynx -dump -listonly "$url" >> "$output"
    sleep 5
    n=$((n-1))
    echo "$n URLs left to process..."
done

Spowoduje to zrzucenie wszystkich łączy do pliku, który możesz dalej przetwarzać w zależności od tego, czego szukasz. Można dodać dodatkowy kod do filtrowania i przetwarzania danych wyjściowych, jednak bez wiedzy, czego potrzebujesz, będziesz musiał nad nim popracować lub zadać dodatkowe pytania.


Aby wyczyścić dane wyjściowe , użyj następującego przykładu:

Przy użyciu „ https://www.google.com ” jako jednego z adresów URL dane wyjściowe wyglądałyby tak:

$ lynx -dump -listonly "https://www.google.com"


References

    1. https://www.google.com/imghp?hl=en&tab=wi
    2. https://maps.google.com/maps?hl=en&tab=wl
    3. https://play.google.com/?hl=en&tab=w8
    4. https://www.youtube.com/?tab=w1

Obciąłem dane wyjściowe, w rzeczywistości jest 19 adresów URL linków.

Aby wynik był tylko listą adresów URL, bez liczb lub białych znaków itp., Użyj awkalbo w połączeniu z, lynxalbo później.

$ lynx -dump -listonly "https://www.google.com" | awk '/:/{print $2}'
https://www.google.com/imghp?hl=en&tab=wi
https://maps.google.com/maps?hl=en&tab=wl
https://play.google.com/?hl=en&tab=w8
https://www.youtube.com/?tab=w1

Jeśli więc chcesz, aby plik wyjściowy był tylko adresem URL łącza, zmień lynxwiersz polecenia na:

lynx -dump -listonly "$url" | awk '/:/{print $2}' >> "$output"

Zawsze możesz przetworzyć zawartość pliku wyjściowego później w skrypcie lub później, aby sprowadzić go do naprawdę pożądanych adresów URL linków i użyć innego parametru wyszukiwania w awk, np. Użyłem „:”, aby wyeliminować puste linie na lynx wyjściu i aby pokazać przykład, w jaki sposób można go filtrować. W tym przykładzie tylko adresy URL linków są przekierowywane do pliku wyjściowego , ponieważ tylko wiersze zawierające dane :wyjściowe get awk, ponieważ wszystkie adresy URL powinny zawierać dwukropek. {print $2}, Uproszczone w tym wyjaśnieniem, usuwa wszystko na lewo od rzeczywistego URL Link.


Oto zaktualizowany skrypt, który sortuje i usuwa zduplikowane adresy URL linków:

#!/bin/bash

urls="/path/to/Input_URLs_List.txt"
output="/path/to/Output_Link_URLs.txt"

n="$(awk 'END {print NR}' "$urls")"
echo "Processing $n URLs..."

cat "$urls" | \
while read url; do
    lynx -dump -listonly "$url" | awk '/:/{print $2}' | sort | uniq >> "$output"
    sleep 5
    n=$((n-1))
    [[ $n -gt 0 ]] &&  echo "$n URLs left to process..." || echo "Processing Completed!"
done

Aktualizacja przechwycić stderr wyjście z lynxdo pliku:

Aby przechwycić stderr wyjście z lynxdo pliku przekierować stderrdo pliku na dysku, np 2>>"$file"dodanej po "$url", na przykład:

lynx -dump -listonly "$url" 2>>"$file" >> "$output"

Dodaj errlog="/path/to/Lynx_Errors.txt"pod, output="/path/to/Output_Link_URLs.txt"a następnie zmień lynxwiersz poleceń na, np .:

lynx -dump -listonly "$url" 2>>"$errlog" >> "$output"

Lub:

lynx -dump -listonly "$url" 2>>"$errlog" | awk '/:/{print $2}' | sort | uniq >> "$output"

Przykład:

#!/bin/bash

urls="/path/to/Input_URLs_List.txt"
output="/path/to/Output_Link_URLs.txt"
errlog="/path/to/Lynx_Errors.txt"

n="$(awk 'END {print NR}' "$urls")"
echo "Processing $n URLs..."

cat "$urls" | \
while read url; do
    lynx -dump -listonly "$url" 2>>"$errlog" | awk '/:/{print $2}' | sort | uniq >> "$output"
    sleep 5
    n=$((n-1))
    [[ $n -gt 0 ]] &&  echo "$n URLs left to process..." || echo "Processing Completed!"
done
użytkownik3439894
źródło
Wiem, że nie powinniśmy używać komentarzy do podziękowań, ale do diabła z zasadami. Dziękuję bardzo! Ogromnie mi pomogłeś.
I0_ol
@ user556068, dodałem przykład do filtrowania danych lynx wyjściowych , więc plik wyjściowy będzie zawierał tylko adresy URL linków, żadnych liczb ani białych znaków itp.
3439894
Tyle informacji. Mogę powiedzieć, że zamierzam nauczyć się wielu nowych rzeczy. Pytanie do Ciebie - jak powinienem utworzyć dziennik błędów, aby śledzić adresy URL, które powodują komunikaty o błędach „ryś: Nie mogę uzyskać dostępu do pliku startowego”?
I0_ol
@ user556068, zobacz zaktualizowaną odpowiedź do przechwytywania stderr wyjścia z lynxdo pliku.
user3439894
Zamiast lynx.... | awk.... | sort | uniqtrylynx -nonumbers -hiddenlinks=merge -dump -listonly "$url" | awk '!a[$0]++'
fd0