Comando de shell o serie de comandos similares a la acción de Automator "Obtener URL de enlace de páginas web"

1

Tengo una larga lista de URLs. Contenidos dentro de cada una de estas páginas web, hay enlaces que necesito extraer. La acción de Automator Obtener URL de enlace de páginas web es una acción muy útil para esta tarea. Desafortunadamente, el propio Automator no maneja muy bien las cargas de trabajo pesadas y muy a menudo se bloquea o se cuelga indefinidamente. ¿Cómo puedo hacer esto con Bash a través de la aplicación Terminal de Mac OS X?

Editar: este es el script actual tal como está ahora.

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

Agregué read -p al principio del script. ¿Existen limitaciones en el número de variables que se pueden usar de esta manera? He utilizado con éxito hasta 9 en las pruebas. ¿Y hay una manera más práctica de escribir esto? Intenté read -p "" {v1..v9} que no funcionó. Agregué un par de bucles for al final para indicar cuántos datos se procesaron.

Problemas actuales

  • a veces me sale un error

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

    sin embargo, cuando se agrega LS_ALL=C a la secuencia de comandos no parece que esto sea correcto.

pregunta I0_ol 27.03.2016 - 01:39

1 respuesta

1

Aquí hay una secuencia de comandos para comenzar:

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

Esto volcará todos los enlaces en un archivo que puede seguir procesando según lo que esté buscando. Se podría agregar código adicional para filtrar y procesar la salida, sin embargo, sin saber qué es lo que necesita, tendrá que trabajar en ello o formular algunas preguntas adicionales.

Para limpiar la salida , use lo siguiente como ejemplo:

Al utilizar " enlace " como una de las URL que se vería con salida :

$ 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

He truncado la salida, en realidad hay 19 URL de enlace.

Para que la salida sea una lista de URL, sin números o espacios en blanco, etc., use awk junto con lynx o posteriormente.

$ 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

Entonces, si desea que el archivo output sea solo las URL del enlace, cambie la línea de comando lynx a:

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

Siempre puede procesar el contenido del archivo output más adelante en el script o posteriormente para llevarlo a las URL de enlace realmente deseadas y usar un parámetro de búsqueda diferente en awk , por ejemplo, usé ":" para eliminar las líneas en blanco en la salida lynx y para mostrar un ejemplo de cómo se puede filtrar. En este ejemplo, solo las URL de enlace se redirigen al archivo output porque solo las líneas que contienen un : obtienen una salida por awk , ya que todas las URL deben tener dos puntos. El {print $2} , simplificado en esta explicación, elimina todo lo que se encuentra a la izquierda de la URL del enlace real.

Aquí hay un script actualizado que ordena y elimina las URL de enlace duplicadas:

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

Actualización para capturar stderr salida de lynx a un archivo:

Para capturar stderr salida de lynx a un archivo, redirige stderr a un archivo de disco, por ejemplo, 2>>"$file" agregado después de "$url" , por ejemplo:

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

Agregue errlog="/path/to/Lynx_Errors.txt" debajo de output="/path/to/Output_Link_URLs.txt" y luego cambie la línea de comando lynx a, por ejemplo:

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

O:

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

Ejemplo :

#!/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
    
respondido por el user3439894 27.03.2016 - 08:45

Lea otras preguntas en las etiquetas