web-dev-qa-db-fra.com

Meilleure façon d'extraire les URL d'une page HTML en utilisant sed ou awk uniquement

Je souhaite extraire l'URL des balises d'ancrage d'un fichier html . Cela doit être effectué dans BASH à l'aide de SED/AWK Pas de Perl s'il vous plait.

Quelle est la manière la plus simple de faire ça?

52
codaddict

Vous pouvez aussi faire quelque chose comme ça (à condition que vous ayez installé Lynx) ...

Versions de Lynx <2.8.8

lynx -dump -listonly my.html

Versions Lynx> = 2.8.8 (courtoisie de @condit)

lynx -dump -hiddenlinks=listonly my.html
53
Hardy

Vous l'avez demandé:

$ wget -O - http://stackoverflow.com | \
  grep -o '<a href=['"'"'"][^"'"'"']*['"'"'"]' | \
  sed -e 's/^<a href=["'"'"']//' -e 's/["'"'"']$//'

Il s’agit d’un outil rudimentaire. Tous les avertissements usuels à propos de la tentative d’analyse HTML avec des expressions régulières s’appliquent.

35
Greg Bacon
grep "<a href=" sourcepage.html
  |sed "s/<a href/\\n<a href/g" 
  |sed 's/\"/\"><\/a>\n/2'
  |grep href
  |sort |uniq
  1. Le premier grep recherche des lignes contenant des URL. Vous pouvez ajouter plus d'éléments .__ après si vous voulez consulter uniquement les pages locales, donc pas de http, mais un chemin relatif
  2. Le premier sed ajoutera une nouvelle ligne devant chaque une balise href url avec le\n
  3. Le second sed raccourcira chaque URL après le second "de la ligne en le remplaçant par le tag/a par un newline Les deux seds vous donneront chaque URL sur une seule ligne, mais il y a
  4. Le 2nd grep href nettoie les dégâts
  5. Le tri et uniq vous donneront une instance de chaque url existante présente dans le fichier sourcepage.html
14
kerkael

Avec l’outil d’extraction de données Xidel - HTML/XML , vous pouvez le faire via:

$ xidel --extract "//a/@href" http://example.com/

Avec conversion en URL absolues:

$ xidel --extract "//a/resolve-uri(@href, base-uri())" http://example.com/
13
Ingo Karkat

Un exemple, puisque vous n'avez fourni aucun échantillon

awk 'BEGIN{
RS="</a>"
IGNORECASE=1
}
{
  for(o=1;o<=NF;o++){
    if ( $o ~ /href/){
      gsub(/.*href=\042/,"",$o)
      gsub(/\042.*/,"",$o)
      print $(o)
    }
  }
}' index.html
11
ghostdog74

J'ai apporté quelques modifications à la solution Greg Bacon

cat index.html | grep -o '<a .*href=.*>' | sed -e 's/<a /\n<a /g' | sed -e 's/<a .*href=['"'"'"]//' -e 's/["'"'"'].*$//' -e '/^$/ d'

Cela corrige deux problèmes:

  1. Nous comparons les cas où l'ancre ne commence pas par href comme premier attribut 
  2. Nous couvrons la possibilité d'avoir plusieurs ancres dans la même ligne
9
Crisboot

Je suppose que vous voulez extraire une URL d'un texte HTML et non pas analyser le HTML (comme le suggère l'un des commentaires). Croyez-le ou non, quelqu'un a déjà fait cela .

OT: Le site Web sed a un lot de bonnes informations et de nombreux scripts sed intéressants/fous. Vous pouvez même jouerSokoban in sed!

5
Alok Singhal

Vous pouvez le faire assez facilement avec la regex suivante, ce qui est très utile pour trouver des URL:

\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))

Je l'ai tirée de article de John Gruber sur la recherche des URL dans le texte }.

Cela vous permet de trouver toutes les URL dans un fichier f.html comme suit:

cat f.html | grep -o \
    -E '\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))'
4
nes1983

Développer la réponse de kerkael :

grep "<a href=" sourcepage.html
  |sed "s/<a href/\\n<a href/g" 
  |sed 's/\"/\"><\/a>\n/2'
  |grep href
  |sort |uniq
# now adding some more
  |grep -v "<a href=\"#"
  |grep -v "<a href=\"../"
  |grep -v "<a href=\"http"

Le premier grep que j'ai ajouté supprime les liens vers les signets locaux.

La seconde supprime les liens relatifs aux niveaux supérieurs.

La troisième supprime les liens qui ne commencent pas par http.

Choisissez lequel vous utilisez selon vos besoins spécifiques.

1
Nikhil VJ

En bash, ce qui suit devrait fonctionner. Notez qu'il n'utilise pas sed ou awk, mais utilise tr et grep, tous les deux très standard et non en Perl ;-)

$ cat source_file.html | tr '"' '\n' | tr "'" '\n' | grep -e '^https://' -e '^http://' -e'^//' | sort | uniq

par exemple:

$ curl "https://www.cnn.com" | tr '"' '\n' | tr "'" '\n' | grep -e '^https://' -e '^http://' -e'^//' | sort | uniq

génère

//s3.amazonaws.com/cnn-sponsored-content
//Twitter.com/cnn
https://us.cnn.com
https://www.cnn.com
https://www.cnn.com/2018/10/27/us/new-york-hudson-river-bodies-identified/index.html\
https://www.cnn.com/2018/11/01/tech/google-employee-walkout-andy-rubin/index.html\
https://www.cnn.com/election/2016/results/exit-polls\
https://www.cnn.com/profiles/frederik-pleitgen\
https://www.facebook.com/cnn
etc...
0
Brad Parks

Voilà comment je l'ai essayé pour une meilleure vue, créer un fichier shell et donner le lien en paramètre, il va créer un fichier temp2.txt.

a=$1

lynx -listonly -dump "$a" > temp

awk 'FNR > 2 {print$2}' temp > temp2.txt

rm temp

>sh test.sh http://link.com
0
Abhishek Gurjar

Tu peux essayer:

curl --silent -u "<username>:<password>" http://<NAGIOS_Host/nagios/cgi-bin/status.cgi|grep 'extinfo.cgi?type=1&Host='|grep "status"|awk -F'</A>' '{print $1}'|awk -F"'>" '{print $3"\t"$1}'|sed 's/<\/a>&nbsp;<\/td>//g'| column -c2 -t|awk '{print $1}'
0
dpathak