web-dev-qa-db-fra.com

Comment utiliser grep et cut in script pour obtenir les URL de sites Web à partir d'un fichier HTML

J'essaie d'utiliser grep et cut pour extraire les URL d'un fichier HTML. Les liens ressemblent à:

<a href="http://examplewebsite.com/">

D'autres sites Web ont .net, .gov, mais je suppose que je pourrais faire le point de coupure juste avant >. Je sais donc que je peux utiliser grep et cut d'une manière ou d'une autre pour tout couper avant http et après .com, mais je suis coincé dessus depuis un moment.

23
eltigre

Comme je l'ai dit dans mon commentaire, ce n'est généralement pas une bonne idée d'analyser le HTML avec des expressions régulières, mais vous pouvez parfois vous en tirer si le HTML que vous analysez se comporte bien.

Afin d'obtenir uniquement les URL qui se trouvent dans l'attribut href de <a> éléments, je trouve plus facile de le faire en plusieurs étapes. D'après vos commentaires, il semble que vous ne souhaitiez que le domaine de premier niveau, pas l'URL complète. Dans ce cas, vous pouvez utiliser quelque chose comme ceci:

grep -Eoi '<a [^>]+>' source.html |
grep -Eo 'href="[^\"]+"' | 
grep -Eo '(http|https)://[^/"]+'

source.html est le fichier contenant le code HTML à analyser.

Ce code imprimera toutes les URL de niveau supérieur qui apparaissent comme l'attribut href de tout <a> éléments dans chaque ligne. Le -i l'option de la première commande grep est de s'assurer qu'elle fonctionnera sur les deux <a> et <A> éléments. Je suppose que vous pourriez également donner -i au 2e grep pour capturer les majuscules HREF attributs, OTOH, je préfère ignorer ce HTML cassé. :)

Pour traiter le contenu de http://google.com/

wget -qO- http://google.com/ |
grep -Eoi '<a [^>]+>' | 
grep -Eo 'href="[^\"]+"' | 
grep -Eo '(http|https)://[^/"]+'

sortie

http://www.google.com.au
http://maps.google.com.au
https://play.google.com
http://www.youtube.com
http://news.google.com.au
https://mail.google.com
https://drive.google.com
http://www.google.com.au
http://www.google.com.au
https://accounts.google.com
http://www.google.com.au
https://www.google.com
https://plus.google.com
http://www.google.com.au

Ma sortie est un peu différente des autres exemples car je suis redirigé vers la page australienne de Google.

26
PM 2Ring

Je ne sais pas si vous êtes limité sur les outils:

Mais l'expression régulière n'est peut-être pas la meilleure façon de procéder, comme mentionné, mais voici un exemple que j'ai rassemblé:

cat urls.html | grep -Eo "(http|https)://[a-zA-Z0-9./?=_-]*" | sort -u
  • grep -E: est le même que egrep
  • grep -o: affiche uniquement ce qui a été récupéré
  • (http | https): est un/ou
  • a-z: est tout en minuscules
  • A-Z: est tout cas supérieur
  • . : est un point
  • /: est la barre oblique
  • ? : est ?
  • *: c'est répéter le [...] groupe
  • sort -u: triera et supprimera tous les doublons

Production:

bob@bob-NE722:~s$  wget -qO- https://stackoverflow.com/ | grep -Eo "(http|https)://[a-zA-Z0-9./?=_-]*" | sort -u
https://stackauth.com
https://meta.stackoverflow.com
https://cdn.sstatic.net/Img/svg-icons
https://stackoverflow.com
https://www.stackoverflowbusiness.com/talent
https://www.stackoverflowbusiness.com/advertising
https://stackoverflow.com/users/login?ssrc=head
https://stackoverflow.com/users/signup?ssrc=head
https://stackoverflow.com
https://stackoverflow.com/help
https://chat.stackoverflow.com
https://meta.stackoverflow.com
...

Vous pouvez également ajouter \d pour capturer d'autres types de chiffres.

27
jmunsch

Si votre grep prend en charge les expressions rationnelles Perl:

grep -Po '(?<=href=")[^"]*(?=")'
  • (?<=href=") et (?=") sont lookaround expressions pour l'attribut href. Cela nécessite le -P option.
  • -o imprime le texte correspondant.

Par exemple:

$ curl -sL https://www.google.com | grep -Po '(?<=href=")[^"]*(?=")'
/search?
https://www.google.co.in/imghp?hl=en&tab=wi
https://maps.google.co.in/maps?hl=en&tab=wl
https://play.google.com/?hl=en&tab=w8
https://www.youtube.com/?gl=IN&tab=w1
https://news.google.co.in/nwshp?hl=en&tab=wn
...

Comme d'habitude, rien ne garantit que ce sont des URI valides ou que le code HTML que vous analysez sera valide.

11
muru

Comme alternative non regex , utilisez pup :

pup 'a[href] attr{href}' < yourfile.html

Recherche tous les éléments a qui ont un attribut href, puis affiche la valeur de l'attribut href.

Pour installer pup, vous avez besoin de Go (un langage de programmation):

Sudo apt-get install golang
Sudo go get github.com/ericchiang/pup

L'avantage de cette solution est qu'elle ne dépend pas du formatage correct du HTML .

8
Kroltan

J'ai trouvé une solution ici qui est à mon humble avis beaucoup plus simple et potentiellement plus rapide que ce qui a été proposé ici. J'ai ajusté un peu pour prendre en charge les fichiers https. Mais la version TD; TR est ...

PS: Vous pouvez remplacer l'URL du site par un chemin d'accès à un fichier et cela fonctionnera de la même manière.

lynx -dump -listonly -nonumbers "http://www.goggle.com" > links.txt

lynx -dump -listonly -nonumbers "some-file.html" > links.txt

Si vous souhaitez simplement voir les liens au lieu de les placer dans un fichier, essayez plutôt ceci ...

lynx -dump -listonly -nonumbers "http://www.google.com"

lynx -dump -listonly -nonumbers "some-file.html"

Le résultat ressemblera à ce qui suit ...

http://www.google.ca/imghp?hl=en&tab=wi
http://maps.google.ca/maps?hl=en&tab=wl
https://play.google.com/?hl=en&tab=w8
http://www.youtube.com/?gl=CA&tab=w1
http://news.google.ca/nwshp?hl=en&tab=wn
https://mail.google.com/mail/?tab=wm
https://drive.google.com/?tab=wo
https://www.google.ca/intl/en/options/
http://www.google.ca/history/optout?hl=en
...
etc.

Pour mon cas d'utilisation, cela a très bien fonctionné. Mais attention, de nos jours, les gens ajoutent des liens comme src = "// blah.tld" pour l'URI CDN des bibliothèques. Je ne voulais pas les voir dans les liens récupérés.

Pas besoin d'essayer de rechercher des liens href ou autres sources car "lynx -dump" extraira par défaut tous les liens cliquables d'une page donnée. Donc, la seule chose que vous devez faire après cela est d'analyser le résultat de "lynx -dump" en utilisant grep pour obtenir une version brute plus propre du même résultat.

1
asiby
wget -qO- google.com |
tr \" \\n | grep https\*://

... ferait probablement très bien. Tel qu'écrit, il imprime:

http://schema.org/WebPage
http://www.google.com/imghp?hl=en&tab=wi
http://maps.google.com/maps?hl=en&tab=wl
https://play.google.com/?hl=en&tab=w8
http://www.youtube.com/?tab=w1
http://news.google.com/nwshp?hl=en&tab=wn
https://mail.google.com/mail/?tab=wm
https://drive.google.com/?tab=wo
http://www.google.com/intl/en/options/
http://www.google.com/history/optout?hl=en
https://accounts.google.com/ServiceLogin?hl=en&continue=http://www.google.com/
https://www.google.com/culturalinstitute/project/the-holocaust?utm_source=google&amp;utm_medium=hppromo&amp;utm_campaign=auschwitz_q1&amp;utm_content=desktop
https://plus.google.com/116899029375914044550

S'il est important de ne faire correspondre que des liens et parmi ces domaines de premier niveau, vous pouvez faire:

wget -qO- google.com |
sed '/\n/P;//!s|<a[^>]*\(https*://[^/"]*\)|\n\1\n|;D'

... ou quelque chose comme ça - bien que pour certains seds vous devrez peut-être remplacer un littéral \nwline caractère pour chacun des deux derniers ns.

Comme écrit, la commande ci-dessus imprime:

http://www.google.com
http://maps.google.com
https://play.google.com
http://www.youtube.com
http://news.google.com
https://mail.google.com
https://drive.google.com
http://www.google.com
http://www.google.com
http://www.google.com
https://www.google.com
https://plus.google.com

... et pour les deux cas (mais probablement le plus utile avec ce dernier) vous pouvez virer de bord sur un |sort -u filtre jusqu'à la fin pour obtenir la liste sorted et supprimer les doublons.

1
mikeserv

Le plus court

grep -r http . --color
0
strash