HTML dosyasından web sitesi URL'leri almak için grep ve komut dosyasında kesme nasıl kullanılır


21

Bir HTML dosyasından URL'leri ayıklamak için grep ve kesim kullanmaya çalışıyorum. Bağlantılar şöyle görünür:

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

Diğer web siteleri de var .net, .govancak daha önce kesme noktasını yapabileceğimi varsayıyorum >. Bu yüzden http ve .com'dan sonra her şeyi kesmek için grep kullanabilir ve bir şekilde kesebilirim, ama bir süredir takıldım.


Ben düzenledim. Bazıları için <ve a arasındaki boşluğu yok sayın, HTML onsuz görünmez. Yakaladığınız için teşekkürler!
eltigre

Kod formatlama kullanın (metni seçin ve Ctrl-K tuşlarına basın). Aksi takdirde, <>HTML etiketi olarak görülmeye zorlar.
muru

neden href parametresinin açılış ve bitiş teklifiyle eşleşmiyor? ayrıca, düzenli ifadelerin html için en uygun olmadığına inanıyorum.
15:50

Özel olarak grep ve bunu yapmak için kes kullanarak bir komut yazmak istiyorum. Başka yollar olduğunu fark ettim, ama bunları bilmek istedim.
eltigre

9
Genel olarak HTML'yi Normal İfadeler ile ayrıştırmak iyi bir fikir değildir, çünkü HTML normal bir dil değildir. Eğer Eğer garanti HTML sen ayrıştırma oldukça basit olduğunu ve özü çalıştığınız şeyler öngörülebilir sen olabilir onunla kurtulmak mümkün. Ancak lütfen stackoverflow.com/a/1732454/4014959
PM 2Ring

Yanıtlar:


25

Yorumumda söylediğim gibi, HTML'yi Normal İfadeler ile ayrıştırmak genellikle iyi bir fikir değildir, ancak ayrıştırdığınız HTML iyi davranıyorsa bazen bundan kurtulabilirsiniz.

Yalnızca öğelerin hrefniteliğindeki URL'leri almak <a>için, bunu birden çok aşamada yapmanın en kolay yolunu bulurum. Yorumlarınızdan, tam URL'yi değil, yalnızca üst düzey alan adını istediğiniz gibi görünüyor. Bu durumda şöyle bir şey kullanabilirsiniz:

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

source.htmlayrıştırılacak HTML kodunu içeren dosya nerede .

Bu kod, her satırdaki öğelerin hrefözniteliği olarak ortaya çıkan tüm üst düzey URL'leri yazdırır <a>. -iİlk seçenek grepkomutuna hem üzerinde çalışacak sağlamaktır <a>ve <A>elemanları. Ben de büyük harf öznitelikleri, OTOH yakalamak -iiçin 2 de verebilir sanırım , böyle kırık HTML göz ardı tercih ederim. :)grepHREF

İçeriğini işlemek http://google.com/

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

çıktı

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

Avustralya Google sayfasına yönlendirildiğim için çıktım diğer örneklerden biraz farklı.


TEŞEKKÜR EDERİM. Şimdi tam da aradığım şey buydu. Bunu yapmanın en temiz yolu bu.
eltigre

@eltigre: Benim için bir zevkti! Ama lütfen yukarıdaki yorumumda bağlantı verdiğim uyarıyı dikkate alın. :)
PM 2Ring

Kolay soruları beklemekle bu soruya geldim ... ve zaten kafasına çiviyi vurmuştun
Mark K Cowan

Teşekkürler @MarkKCowan. :) FWIW, aslında awk kullanarak bir cevap yazmaya başladım, ama sonra awk'a aşina olmayanlar için grep tabanlı bir çözümün daha kolay anlaşılacağına karar verdim. Her neyse, yukarıdaki kod awk kodumdan daha kısa.
PM 2Ring

2
@mavavilj: Çünkü OP sadece en üst seviye alanı istedi, bu yüzden sadece ilkinden ://önce karakterleri kabul ettik /ya da ". Ancak tam URL'yi görmek istiyorsanız, bu komutu olarak değiştirin grep -Eo '(http|https)://[^"]+. Bu satır için başka bir seçenek de grep -Eo '(http|https)://[^?"]+'sorgu seçeneklerini kesen yöntemdir. Ancak, bu varyasyon yine de bir sorgu parametresi olarak başka bir URL'de bulunan URL'leri yazdırır, ancak ayrı bir satıra yazdırılır.
PM 2Ring

25

Araçlarla sınırlı olup olmadığınızdan emin değilim:

Ancak normal ifade, belirtildiği gibi gitmenin en iyi yolu olmayabilir, ancak işte bir araya getirdiğim bir örnek:

cat urls.html | grep -Eo "(http|https)://[a-zA-Z0-9./?=_-]*" | sort -u
  • grep -E: egrep ile aynı
  • grep -o: sadece karşıt olanları çıkarır
  • (http | https): bir veya
  • az: hepsi küçük harf
  • AZ: hepsi daha iyi durumda
  • . : nokta
  • \?: dır-dir ?
  • *: [...] grubunu tekrar eder
  • uniq: kopyaları kaldıracak

Çıktı:

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

\dDiğer sayı türlerini yakalamak için de ekleyebilirsiniz .


2
IRI normal ifadeleri! Bunlardan birini kullanın ve OP'yi korkutun! :)
muru

2
@muru ... titriyorum ben ... ne diyeceğimi bilmiyorum. Bunlar gerçek mi !?
jmunsch

4
@jmunsch, uniq sadece bitişik kopyaları kaldırın. sort -u?
JJoao

1
harika çalışıyor, en iyi cevap !!
Gery

@JJoao sıralamak için kaynak-u boru daha hızlı? Sadece bir düşünce deneyi, bakmalıyım. Ama muhtemelen haklısın, kabuk katmanı konusunda.
jmunsch

9

Grep'iniz Perl normal ifadelerini destekliyorsa:

grep -Po '(?<=href=")[^"]*(?=")'
  • (?<=href=")ve (?=")olan etrafa bakma için ifadeleri hrefözniteliği. Bu -Pseçeneğe ihtiyaç duyar .
  • -o eşleşen metni yazdırır.

Örneğin:

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

Her zaman olduğu gibi, bunların geçerli URI'ler veya ayrıştırdığınız HTML'nin geçerli olacağının garantisi yoktur.


8

Normal olmayan bir alternatif olarak pup'ı kullanın :

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

Tüm aöğeleri bulacaktırhrefÖzniteliği , ardından özniteliğin değerini görüntüler href.

Yüklemek için pupGo (bir programlama dili) gerekir:

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

Bu çözümün avantajı, doğru biçimlendirilmiş HTML'ye dayanmamasıdır .


1
+1 pup, bunu yükleme zamanı ....
Mark K Cowan

Bunları dosyaya da koyabilirsiniz. pup 'a.classname[href] attr{href}' < tut.html >links.md
Ahmad Awais

1

Burada IMHO'nun burada önerilenden çok daha basit ve potansiyel olarak daha hızlı bir çözüm buldum . Https dosyalarını desteklemek için biraz ayarladım. Ama TD; TR versiyonu ...

Not: Site URL'sini bir dosya yolu ile değiştirebilirsiniz; bu URL aynı şekilde çalışır.

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

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

Bağlantıları bir dosyaya yerleştirmek yerine görmek istiyorsanız, bunun yerine bunu deneyin ...

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

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

Sonuç aşağıdakine benzer olacaktır ...

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.

Benim kullanım durumum için, bu iyi çalıştı. Ancak günümüzde insanların kütüphanelerin CDN URI'sına src = "// blah.tld" gibi bağlantılar eklediklerine dikkat edin. Bunları geri alınan bağlantılarda görmek istemedim.

"Lynx -dump" varsayılan olarak belirli bir sayfadaki tıklanabilir tüm bağlantıları ayıklayacağından, href veya diğer kaynaklar için bağlantı kontrol etmeye çalışmanıza gerek yoktur. Bundan sonra yapmanız gereken tek şey, aynı sonucun daha temiz bir ham sürümünü elde etmek için grep kullanarak "vaşak-dökümü" nin sonucunu ayrıştırmaktır.


Ancak soru, " URL'leri bir web sayfasından çıkar" DEĞİL "URL'leri [benzeyen] bir HTML dosyasından çıkar " (örnek) diyor. Cevabınız yerel makinede bulunan bir dosyada kullanılabiliyorsa nasıl yapılacağını açıklayın. Lütfen yorumlarda yanıt vermeyin; daha net ve eksiksiz hale getirmek için cevabınızı düzenleyin .
G-Man, '

1
URL'yi bir dosya adıyla değiştirebilirsiniz.
asiby

@ G-Man, neden -1? Kodu kendiniz denemeniz ve yerel dosyalar için de çalıştığını görmeniz gerekir. Açıkça görülmemesi durumunda bu açıklamayı ekledim.
asiby

Bu gerçekten kullanışlıdır .. xargs ile kullanıyorsanız eklemeye değer | sırala | yinelenen bağlantıları kırpmak için uniq.
Stuart Axon

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

... muhtemelen oldukça iyi olurdu. Yazıldığı gibi yazdırır:

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

Yalnızca bağlantıları eşleştirmeniz ve bu üst düzey alanlardan birini seçmeniz önemlidir:

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

... ya da onun gibi bir şey - bazı seds \niçin son iki karakterin her biri yerine gerçek bir ewline karakteri koymanız gerekebilir n.

Yazıldığı gibi, yukarıdaki komut yazdırılır:

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

... ve her iki durumda da (ancak muhtemelen ikincisi için en faydalı olanı)|sort -u listeyi almak sortve kopyaları bırakmak için sonuna kadar bir filtreye yapıştırabilirsiniz .



-1
echo "<a href="http://examplewebsite.com/">"|sed -r 's:<.*"::g'|sed 's:/">$::g'

Bu "akıllı" alıntıların orada istediğiniz gibi olduğundan emin değilim - belki de düzenli "çift" alıntılar?
Jeff Schaller
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.