Como usar grep e cut in script para obter URLs de sites de um arquivo HTML

15

Estou tentando usar grep e cut para extrair URLs de um arquivo HTML. Os links parecem:

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

Outros sites têm .net , .gov , mas suponho que posso fazer o ponto de corte antes de > . Então eu sei que posso usar grep e cortar de alguma forma para cortar tudo antes de http e depois de .com, mas fiquei preso nele por um tempo.

    
por eltigre 27.01.2015 / 05:32

7 respostas

23

Como eu disse no meu comentário, geralmente não é uma boa ideia analisar HTML com Expressões Regulares, mas às vezes você pode se safar se o HTML que você está analisando for bem comportado.

Para obter somente os URLs que estão no atributo href de <a> elements, acho mais fácil fazer isso em vários estágios. De seus comentários, parece que você deseja apenas o domínio de nível superior, não o URL completo. Nesse caso, você pode usar algo assim:

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

em que source.html é o arquivo que contém o código HTML para analisar.

Este código imprimirá todos os URLs de nível superior que ocorrerem como o atributo href de todos os elementos <a> em cada linha. A opção -i para o primeiro comando grep é para garantir que funcionará nos elementos <a> e <A> . Eu acho que você também poderia dar -i ao segundo grep para capturar os atributos HREF em maiúsculas, OTOH, eu prefiro ignorar esse HTML corrompido. :)

Para processar o conteúdo de http://google.com/

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

saída

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

Minha saída é um pouco diferente dos outros exemplos, já que sou redirecionada para a página do Google australiana.

    
por 27.01.2015 / 07:09
15

Não tenho certeza se você está limitado em ferramentas:

Mas regex pode não ser o melhor caminho a seguir, mas aqui está um exemplo que eu coloquei:

cat urls.html | grep -Eo "(http|https)://[a-zA-Z0-9./?=_-]*" | sort | uniq
  • grep -E: é o mesmo que egrep
  • grep -o: apenas mostra o que foi grepped
  • (http | https): é um ou / ou
  • a-z: é todo em minúsculas
  • A-Z: é tudo um bom caso
  • : é ponto
  • \ ?: é?
  • *: repete o grupo
  • uniq: removerá quaisquer duplicatas

Saída:

bob@bob-NE722:~s$ wget -qO- http://google.com/ | grep -Eo "(http|https)://[\da-z./?A-Z0-9\D=_-]*" | uniq
http://schema.org/WebPage
http://www.google.com/imghp?hl=en
http://maps.google.com/maps?hl=en
https://play.google.com/?hl=en
http://www.youtube.com/?tab=w1
http://news.google.com/nwshp?hl=en
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
http://www.google.com/
https://www.google.com/culturalinstitute/project/the-holocaust?utm_source=google
https://plus.google.com/116899029375914044550
    
por 27.01.2015 / 06:02
6

Se o seu grep suportar regexes Perl:

grep -Po '(?<=href=")[^"]*(?=")'
  • (?<=href=") e (?=") são expressões lookaround para o atributo href . Isso precisa da opção -P .
  • -o imprime o texto correspondente.

Por exemplo:

$ 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
...

Como de costume, não há garantia de que esses sejam URIs válidos ou que o HTML que você está analisando seja válido.

    
por 27.01.2015 / 05:56
4

Como alternativa sem regex , use filhote :

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

Encontrará todos os elementos a que têm um atributo href e, em seguida, exibirá o valor do atributo href .

Para instalar o pup , você precisa do Go (uma linguagem de programação):

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

A vantagem desta solução é que não confie no HTML que está sendo formatado corretamente .

    
por 27.01.2015 / 11:21
1

Eu encontrei uma solução aqui que é IMHO muito mais simples e potencialmente mais rápida do que o que foi proposto aqui. Eu ajustei um pouco para suportar arquivos https. Mas a versão do TD; TR é ...

PS: você pode substituir o URL do site por um caminho para um arquivo e ele funcionará da mesma maneira.

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

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

Se você quiser apenas ver os links em vez de colocá-los em um arquivo, tente isso ...

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

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

O resultado será semelhante ao seguinte ...

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.

Para o meu caso de uso, isso funcionou muito bem. Mas cuidado com o fato de que hoje em dia, as pessoas adicionam links como src="// blah.tld" para CDN URI de bibliotecas. Eu não queria ver aqueles nos links recuperados.

Não é necessário tentar verificar href ou outras fontes de links, porque "lynx -dump" irá, por padrão, extrair todos os links clicáveis de uma determinada página. Então, a única coisa que você precisa fazer depois disso é analisar o resultado de "lynx -dump" usando o grep para obter uma versão raw mais limpa do mesmo resultado.

    
por 07.12.2017 / 02:02
0
wget -qO- google.com |
tr \" \n | grep https\*://

... provavelmente se sairia bem. Conforme escrito, 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

Se for importante que você corresponda apenas aos links e entre esses domínios de nível superior, faça:

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

... ou algo parecido. No entanto, para alguns sed s, talvez seja necessário substituir um caractere literal \n ewline por cada um dos dois últimos n s.

Conforme escrito, o comando acima 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

... e para qualquer um dos casos (mas provavelmente mais útil com o último) você pode adicionar um |sort -u ao final para obter a lista sort ed e remover duplicatas .

    
por 27.01.2015 / 08:50
-1
echo "<a href="http://examplewebsite.com/">"|sed -r 's:<.*"::g'|sed 's:/">$::g'
    
por 07.12.2017 / 02:43