1 votes

Commande shell ou série de commandes similaire à l'action Automator "Obtenir les URLs des liens des pages Web"

J'ai une longue liste d'URL. Contenu à l'intérieur de chaque page Web, il y a des liens que je dois extraire. L'action Automator Obtenir les URL des liens à partir des pages Web est une action très utile pour cette tâche. Malheureusement, Automator lui-même ne gère pas très bien les charges de travail lourdes et plante souvent ou reste bloqué indéfiniment. Comment pourrais-je procéder en utilisant Bash via l'application Terminal Mac OS X ?

Éditer - voici le script actuel tel qu'il est maintenant.

#!/bin/bash

echo "Entrez jusqu'à 3 mots"
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 "Traitement de $n URL..."

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 URL restant à traiter..." || echo "Traitement terminé!"
done

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

for r in "Résultats de cette session"; do echo "$(cat "$fin" | wc -l)" "$r"; done
for a in "URL archivées"; do echo "$(cat "$arc" | wc -l)" "$a"; done

J'ai ajouté read -p au début du script. Y a-t-il des limitations sur le nombre de variables qui peuvent être utilisées de cette manière ? J'ai réussi à en utiliser jusqu'à 9 en testant. Et y a-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 boucles for à la fin pour indiquer combien de données ont été traitées.

Problèmes actuels

  • parfois j'obtiens une erreur

    sort: comparaison de chaînes a échoué : Séquence de byte incorrecte
    sort: Définissez LC_ALL='C' pour contourner le problème.

    cependant lorsque j'ajoute LS_ALL=C au script, cela ne semble pas correct.

0 votes

J'ai déjà installé lynx via Homebrew.

0 votes

D'accord alors. À mon avis, écrire un script bash en utilisant lynx pour obtenir les liens à partir de la liste d'URL est la meilleure solution. Avec les URL cibles dans un fichier texte, un par ligne, le fichier peut être lu ligne par ligne et traité dans une boucle avec un minuteur afin de ne pas surcharger trop rapidement le serveur si les URL pointent vers le même domaine et/ou simplement pour rythmer les choses de manière appropriée. Toutes les sorties sont mises dans un autre fichier pour être filtrées selon les besoins afin d'obtenir une liste d'URL souhaitée. Avez-vous besoin d'aide avec le script?

0 votes

Oui, ce serait super si vous pouviez le faire. Je commence à apprendre bash mais je suis très novice en la matière. J'ai les URL dans un fichier texte brut, un par ligne. Je ne suis juste pas sûr de ce que je dois faire ensuite.

1voto

user3439894 Points 52496

Voici un script pour vous aider :

#!/bin/bash

urls="/chemin/vers/Liste_d_URL_d_entree.txt"
output="/chemin/vers/URLs_de_liens_de_sortie.txt"

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

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

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


Pour nettoyer la sortie, utilisez ceci comme exemple :

En utilisant "https://www.google.com" comme l'un des URL, la sortie ressemblerait à ceci :

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

Références

    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 juste une liste d'URL, sans numéros ni espace, etc., utilisez awk soit en conjonction avec lynx soit après.

$ 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 contienne juste les URL de liens, changez la ligne de commande lynx en :

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

Vous pouvez toujours traiter ultérieurement le contenu du fichier de sortie dans le script ou après pour le réduire aux URL de liens vraiment voulu et utiliser un autre paramètre de recherche dans awk, par exemple, j'ai utilisé ":" pour éliminer les lignes vides dans la sortie de lynx et montrer un exemple de filtrage. Dans cet exemple, seuls les URL de liens sont redirigés dans le fichier de sortie car seules les lignes contenant un : sont affichées par awk, car tous les URL devraient avoir un deux-points en eux. Le {print $2}, simplifié dans cette explication, supprime tout à gauche de l'URL de lien réel.


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

#!/bin/bash

urls="/chemin/vers/Liste_d_URL_d_entree.txt"
output="/chemin/vers/URLs_de_liens_de_sortie.txt"

n="$(awk 'END {print NR}' "$urls")"
echo "Traitement de $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 restantes à traiter..." || echo "Traitement terminé!"
done

Mise à jour pour capturer la stderr sortie de lynx dans un fichier :

Pour capturer la stderr sortie de lynx dans un fichier, redirigez stderr vers un fichier disque, par exemple, 2>>"$fichier" ajouté après "$url", par exemple :

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

Ajoutez errlog="/chemin/vers/Erreurs_Lynx.txt" sous output="/chemin/vers/URLs_de_liens_de_sortie.txt" puis changez la ligne de commande lynx 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="/chemin/vers/Liste_d_URL_d_entree.txt"
output="/chemin/vers/URLs_de_liens_de_sortie.txt"
errlog="/chemin/vers/Erreurs_Lynx.txt"

n="$(awk 'END {print NR}' "$urls")"
echo "Traitement de $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 restantes à traiter..." || echo "Traitement terminé!"
done

0 votes

Je sais que nous ne sommes pas censés utiliser les commentaires pour dire merci, mais bon sang avec les règles.. Merci beaucoup! Tu m'as énormément aidé.

0 votes

@user556068, J'ai ajouté un exemple pour filtrer la lynx output, donc le outfile contiendra uniquement des URL de liens, sans chiffres ni espaces, etc.

0 votes

Tant d'informations. Je peux dire que je suis sur le point d'apprendre beaucoup de nouvelles choses. Question pour vous - Comment pourrais-je créer un journal d'erreurs pour suivre les URL qui causent des messages d'erreur "lynx: impossible d'accéder au fichier de démarrage" ?

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X