Commande Shell ou série de commandes similaire à l'action Automator «Obtenir les URL de lien des pages Web».

1

J'ai une longue liste d'URL. Chacune de ces pages Web contient des liens que je dois extraire. L'action Automator Obtenir les URL de lien des pages Web est une action très utile pour cette tâche. Malheureusement, Automator ne gère pas très bien les lourdes charges de travail et se bloque ou se bloque indéfiniment très souvent. Comment puis-je m'y prendre à l'aide de Bash via l'application Mac OS X Terminal?

Edit - c'est le script actuel tel qu'il est actuellement.

#!/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

J'ai ajouté read -pau début du script. Y a-t-il des limites au nombre de variables pouvant être utilisées de la sorte? J'ai utilisé avec succès jusqu'à 9 tests. Et existe-t-il un moyen plus pratique d'écrire cela? J'ai essayé read -p "" {v1..v9}qui n'a pas fonctionné. J'ai ajouté quelques forboucles à la fin pour indiquer combien de données ont été traitées.

Questions d'actualité

  • parfois je reçois une erreur

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

    cependant, lorsque vous ajoutez LS_ALL=Cau script, cela ne semble pas correct.

I0_ol
la source
En fait, j'ai déjà installé Lynx via Homebrew.
I0_ol
Ok alors. OMI écrit un script bash en utilisant Lynx pour obtenir les liens de la liste des URL est le chemin à parcourir. Avec les URL cibles dans un fichier texte, une par ligne, le fichier peut être lu ligne par ligne et traité en boucle avec une minuterie afin de ne pas forcer le serveur à se hâter si les URL pointent vers le même domaine et ou juste pour calmer les choses de manière appropriée. Toutes les sorties sont placées dans un autre fichier à filtrer selon les besoins pour accéder à la liste des URL recherchées. Avez-vous besoin d'aide avec le script?
user3439894
Oui, ce serait formidable si vous le pouviez. Je commence à apprendre le bash mais je suis très novice. J'ai les URL dans un fichier texte brut un par ligne. Juste pas sûr où aller à partir de là.
I0_ol

Réponses:

1

Voici un script pour vous aider à démarrer:

#!/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

Cela va vider tous les liens dans un fichier que vous pouvez traiter en fonction de ce que vous recherchez. Du code supplémentaire pourrait être ajouté pour filtrer et traiter la sortie. Toutefois, sans savoir de quoi vous avez besoin, vous devrez travailler dessus et poser des questions supplémentaires.


Pour nettoyer la sortie , utilisez l'exemple suivant:

En utilisant " https://www.google.com " comme une des URL, le résultat devrait ressembler à ceci:

$ 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

J'ai tronqué la sortie, il y a en fait 19 URL de liens.

Pour que la sortie soit simplement une liste d'URL, sans chiffres ni espaces, etc., utilisez- awkles conjointement lynxou ultérieurement.

$ 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

Donc, si vous voulez que le fichier de sortie ne soit que les URL de lien, modifiez la lynxligne de commande pour:

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

Vous pouvez toujours traiter le contenu du fichier de sortie plus tard dans le script ou ultérieurement pour le réduire aux URL de lien réellement recherchées et utiliser un paramètre de recherche différent dans awk, par exemple, j'ai utilisé ":" pour éliminer à la fois les lignes vides dans la lynx sortie. et pour montrer un exemple de la façon dont il peut être filtré. Dans cet exemple, seules les URL de lien sont redirigées dans le fichier de sortie car seules les lignes contenant une :sortie en obtiennent awk, car toutes les URL doivent comporter un signe deux-points. Le {print $2}, simplifié dans cette explication, supprime tout ce qui se trouve à gauche de l'URL de lien réelle.


Voici un script mis à jour qui trie et supprime les URL de lien en double:

#!/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

Mise à jour pour capturer la stderr sortie d' lynxun fichier:

Pour capturer la stderr sortie d' lynxun fichier, redirigez-le stderrvers un fichier sur disque, par exemple, 2>>"$file"ajouté après "$url", par exemple:

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

Ajouter en- errlog="/path/to/Lynx_Errors.txt"dessous output="/path/to/Output_Link_URLs.txt"et changer la lynxligne de commande en, par exemple:

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

Ou:

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

Exemple:

#!/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
utilisateur3439894
la source
Je sais que nous ne sommes pas censés utiliser les commentaires pour remercier mais au diable les règles .. Merci beaucoup! Vous m'avez énormément aidé.
I0_ol
@ user556068, j'ai ajouté un exemple pour filtrer la lynx sortie , de sorte que le fichier de sortie ne contienne que des URL de lien, aucun chiffre ni espace, etc.
user3439894
Tant d'informations. Je peux dire que je suis sur le point d'apprendre beaucoup de nouvelles choses. Question pour vous - Comment puis-je créer un journal des erreurs pour garder une trace des URL qui provoquent des messages d'erreur "lynx: Impossible d'accéder à startfile"?
I0_ol
@ user556068, Voir la réponse mise à jour pour capturer la stderr sortie d' lynxun fichier.
user3439894
Au lieu d' lynx.... | awk.... | sort | uniqessayerlynx -nonumbers -hiddenlinks=merge -dump -listonly "$url" | awk '!a[$0]++'
fd0