Le moyen le plus simple 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 fait dans BASH en utilisant SED / AWK. Pas de perl s’il vous plait

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

Vous pourriez aussi faire quelque chose comme ça (à condition que lynx soit installé) …

Versions Lynx <2.8.8

lynx -dump -listonly my.html 

Versions Lynx> = 2.8.8 (avec la permission de @condit)

 lynx -dump -hiddenlinks=listonly my.html 

Vous l’avez demandé:

 $ wget -O - http://stackoverflow.com | \ grep -o ' 

C'est un outil brut, donc tous les avertissements habituels sur la tentative d'parsing du HTML avec des expressions régulières s'appliquent.

 grep "<\/a>\n/2' |grep href |sort |uniq 
  1. Le premier grep recherche les lignes contenant des URL. Vous pouvez append plus d’éléments après si vous voulez regarder uniquement sur les pages locales, donc pas de http, mais un chemin relatif.
  2. Le premier sed appenda une nouvelle ligne devant chaque balise d’URL href avec le \ n
  3. La deuxième sed raccourcira chaque URL après la 2ème “dans la ligne en la remplaçant par la balise / a avec une nouvelle ligne. Les deux seds vous donneront chaque URL sur une seule ligne, mais il y a des erreurs, donc
  4. Le 2nd grep href nettoie les dégâts
  5. Le sorting et l’uniq vous donneront une instance de chaque URL existante présente dans la page source.html

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

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

Avec la conversion en URL absolues:

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

Un exemple, puisque vous n’avez pas fourni d’échantillon

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

J’ai apporté quelques modifications à Greg Bacon Solution

 cat index.html | grep -o '' | sed -e 's/ 

Cela corrige deux problèmes:

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

Vous pouvez le faire assez facilement avec la regex suivante, ce qui est assez bon pour trouver des URL:

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

Je l’ai pris de l’article de John Gruber sur la façon de trouver des URL dans un 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]|/)))' 

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

OT: Le site sed a beaucoup d’informations et de nombreux scripts sed intéressants. Vous pouvez même jouer à Sokoban dans sed!

Passez à la première passe en remplaçant le début des URL (http) par une nouvelle ligne ( \n http). Ensuite, vous vous êtes assuré que votre lien commence au début de la ligne et est la seule URL de la ligne.

Le rest devrait être facile, voici un exemple:

sed "s/http/\nhttp/g" <(curl "http://www.cnn.com") | sed -n "s/\(^http[s]*:[a-Z0-9/.=?_-]*\)\(.*\)/\1/p"

alias lsurls='_(){ sed "s/http/\nhttp/g" "${1}" | sed -n "s/\(^http[s]*:[a-Z0-9/.=?_-]*\)\(.*\)/\1/p"; }; _'

En élargissant la réponse de Kerkael :

 grep "<\/a>\n/2' |grep href |sort |uniq # now adding some more |grep -v " 

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

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

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

Choisissez et choisissez celui que vous utilisez selon vos besoins spécifiques.

Tu peux essayer:

 curl --silent -u ":" http://" '{print $3"\t"$1}'|sed 's/<\/a> <\/td>//g'| column -c2 -t|awk '{print $1}' 

C’est ainsi que je l’ai essayé pour mieux voir, créer un fichier shell et donner un lien en paramètre, cela 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 

Ceci est mon premier article, alors j’essaie de faire de mon mieux pour expliquer pourquoi je publie cette réponse …

  1. Comme les 7 premières réponses les plus votées, 4 incluent le GREP, même si le message dit explicitement “utiliser sed ou awk uniquement”.
  2. Même lorsque le message nécessite “No perl please”, en raison du point précédent, et parce que vous utilisez PERLE regex dans grep.
  3. et parce que c’est le moyen le plus simple (pour autant que je sache et était requirejs) de le faire dans BASH.

Donc voici le script le plus simple de GNU grep 2.28:

 grep -Po 'href="\K.*?(?=")' 

A propos du commutateur \K , pas d’info a été créée dans les pages MAN et INFO, alors je suis venu ici pour la réponse …. le commutateur \K débarrasse les caractères précédents (et la clé elle-même). Gardez à l’esprit suivant les conseils de man pages: “Ceci est très expérimental et grep -P peut avertir des fonctionnalités non implémentées.”

Bien sûr, vous pouvez modifier le script pour répondre à vos goûts ou à vos besoins, mais je l’ai trouvé assez direct pour ce qui était demandé dans le post, et aussi pour beaucoup d’entre nous …

J’espère que les gens vous trouvent très utile.

Merci!!!