URL listesinin HTTP durum kodunu almak için komut dosyası?


89

Hala çalışıp çalışmadıklarını görmek için kontrol etmem gereken URL'lerin bir listesi var. Bunu benim için yapan bir bash senaryosu yazmak istiyorum.

Sadece döndürülen HTTP durum koduna ihtiyacım var, yani 200, 404, 500 vb. Daha fazlası yok.

DÜZENLE Sayfa "404 bulunamadı" diyor, ancak 200 OK mesajı veriyorsa bir sorun olduğunu unutmayın. Bu yanlış yapılandırılmış bir web sunucusudur, ancak bu durumu dikkate almanız gerekebilir.

Bununla ilgili daha fazla bilgi için "404" metnini içeren bir sayfaya URL'nin gidip gitmediğini kontrol etme konusuna bakın.


2
Dürüst olmak gerekirse, betiğimin "hatası" yalnızca sunucu HTTP kodu 200 döndürdüğünde, ancak gövde metninde yanlış davranan bir web sunucusu olan "404 bulunamadı" diyor.
Phil

2
Cevap kodu 200 ise wget'in çıkış durumu 0, 404 ise 8, 302 ise 4 olacaktır ... $? önceki komutun çıkış durumuna erişmek için değişken.
Casey Watson

Yanıtlar:


198

Curl'ün bunun için belirli bir seçeneği vardır --write-out:

$ curl -o /dev/null --silent --head --write-out '%{http_code}\n' <url>
200
  • -o /dev/null olağan çıktıyı atar
  • --silent ilerleme ölçeri fırlatır
  • --head GET yerine HEAD HTTP isteğinde bulunur
  • --write-out '%{http_code}\n' gerekli durum kodunu yazdırır

Bunu eksiksiz bir Bash betiğinde özetlemek için:

#!/bin/bash
while read LINE; do
  curl -o /dev/null --silent --head --write-out "%{http_code} $LINE\n" "$LINE"
done < url-list.txt

(Kartal gözlü okuyucular bunun her URL için çatal ve TCP bağlantı cezaları uygulayan bir curl işlemi kullandığını fark edeceklerdir. Birden çok URL tek bir curl'de birleştirilirse daha hızlı olur, ancak bu canavarca tekrarları yazmak için yer yoktur bunu yapmak için curl gerektiren seçenekler.)


Çok hoş. Bu komutu dosyamdaki her url'de çalıştırabilir miyim?
Manu

1
@Manu: Evet, cevabımı curl komutunu tamamlamanın olası bir yolunu gösterecek şekilde düzenledim. Url-list.txt dosyasının satır başına bir URL içerdiğini varsayar.
Phil

1
Neden yukarıdan gelen komut dosyası ve çıktıda her zaman bana 000 getirdiğini bilmiyorum, ancak komutu döngü olmadan yalnızca bir kez çalıştırdığımda işe yarıyor ...
Karol F

1
@KarolFiturski Aynı problemi yaşadım (muhtemelen o zamandan beri düzelttiniz, ancak başka birinin buna rastlaması durumunda ...) benim durumumda girdi dosyamın satır sonlarında satır başları vardı ve url'lerin şöyle olmasına neden oldu http://example.com/\rdöngüden geçerken
Jordan Robinson

1
Bu sorunu yaşadım ve Windows türünden biten satırı Linux türüne geçirerek düzeltmeyi başardım.
Tristan

38
wget --spider -S "http://url/to/be/checked" 2>&1 | grep "HTTP/" | awk '{print $2}'

sadece sizin için durum kodunu yazdırır


9
+1 Bir url yeniden yönlendirildiğinde, her biri yeni satırda olmak üzere birden çok kod gösterir.
Ashfame

Yapmaya çalıştığım istekle çalışması için --spider'dan kurtulmam gerekiyordu, ama çalışıyor.
amitavk

30

Phil tarafından zaten verilen cevabı genişletmek. Eğer arama için xargs kullanırsanız, buna paralellik eklemek, bash'de akıllıca değildir.

İşte kod:

xargs -n1 -P 10 curl -o /dev/null --silent --head --write-out '%{url_effective}: %{http_code}\n' < url.lst

-n1 : curl çağrısı için bağımsız değişken olarak (listeden) yalnızca bir değer kullanın

-P10 : Herhangi bir zamanda 10 curl işlemini canlı tutun (yani 10 paralel bağlantı)

write_outKullanarak ayıklayabileceğiniz daha fazla veri için curl kılavuzundaki parametreyi kontrol edin (saatler, vb.).

Birine yardımcı olması durumunda şu anda kullandığım arama bu:

xargs -n1 -P 10 curl -o /dev/null --silent --head --write-out '%{url_effective};%{http_code};%{time_total};%{time_namelookup};%{time_connect};%{size_download};%{speed_download}\n' < url.lst | tee results.csv

Sadece bir grup veriyi herhangi bir ofis aracına aktarılabilen bir csv dosyasına çıkarır.


2
Paralellik, dosya girişi ve csv. Tam olarak aradığım şey.
Agey

Harika, günümü yarattı.
xlttj

Bu harika, tam aradığım şey, teşekkürler efendim. Bir soru, sayfanın sayfa başlığı csv sonuçlarına nasıl dahil edilebilir?
MitchellK

@estani - stackoverflow.com/users/1182464/estani , bir sayfanın sayfa başlığının .csv dosyasına alınmasını nasıl içerebilir? Yeniden yayınladığım için özür dilerim, bu soru hakkında bilgilendirilmek için sizi etiketlemeyi unuttum. Çok teşekkürler.
MitchellK

@MitchellK, bu http çağrısının içeriğini hiç ele almıyor. "Sayfa başlığı" (her ne ise) url'de bulunuyorsa, onu ekleyebilirsiniz. Değilse, "başlığını" çıkarmak için tüm sayfayı ayrıştırmanız gerekir (http tarafından alınan bir html sayfasını kastettiğinizi varsayarsak). Yığın taşmasında başka yanıtlar arayın veya belirli bir soruyu sorun.
estani

17

Bu wget, Alpine Linux'ta bile yaygın olarak bulunmasına, hemen hemen her yerde mevcut olmasına dayanır .

wget --server-response --spider --quiet "${url}" 2>&1 | awk 'NR==1{print $2}'

Açıklamalar aşağıdaki gibidir:

--quiet

Wget'in çıktısını kapatın.

Kaynak - wget man Pages

--spider

[...] sayfaları indirmeyecek, sadece orada olduklarını kontrol edin. [...]

Kaynak - wget man Pages

--server-response

HTTP sunucuları tarafından gönderilen başlıkları ve FTP sunucuları tarafından gönderilen yanıtları yazdırın.

Kaynak - wget man Pages

Söylemedikleri şey --server-response, bu başlıkların çıktısının standart hataya (sterr) yazdırılması , dolayısıyla stdin'e yeniden yönlendirme ihtiyacıdır .

Standart girdiye gönderilen çıktı awk, HTTP durum kodunu çıkarmak için onu yönlendirebiliriz . Bu kod:

  • ikinci ( $2) boş olmayan karakter grubu:{$2}
  • başlığın ilk satırında: NR==1

Ve bunu yazdırmak istiyorum, çünkü ... {print $2}.

wget --server-response --spider --quiet "${url}" 2>&1 | awk 'NR==1{print $2}'

1
Bunu ile kullandım2>&1 | head -1 | awk '{ print $2 }'
Evhz

7

Kullanım curlHTTP başlığını sadece (bütün dosyası) alıp bunu ayrıştırmak için:

$ curl -I  --stderr /dev/null http://www.google.co.uk/index.html | head -1 | cut -d' ' -f2
200

wget 404 dediğinde curl bana 200 diyor ... :(
Manu

-IBayrak nedenleri bazı sunucular tarafından HTTP GET normal ayrı tedavi edilir ve böylece farklı değerler döndürebilir bir HTTP HEAD isteği yapmak için kıvırın. Komut hala onsuz çalışmalıdır.
lambshaanxy

4

wget -S -i *file* size bir dosyadaki her url'den başlıkları alacak.

Yine grepde özellikle durum kodu için filtre uygulayın .


1

Python'da yazılmış bir "webchk" aracı buldum. URL listesi için bir durum kodu döndürür. Https://pypi.org/project/webchk/

Çıktı şuna benzer:

▶ webchk -i ./dxieu.txt | grep '200'
http://salesforce-case-status.dxi.eu/login ... 200 OK (0.108)
https://support.dxi.eu/hc/en-gb ... 200 OK (0.389)
https://support.dxi.eu/hc/en-gb ... 200 OK (0.401)

Umarım yardımcı olur!


0

Https://mywiki.wooledge.org/BashPitfalls#Non-atomic_writes_with_xargs_-P ( xargskarışık risklerde paralel işlerden elde edilen çıktı) nedeniyle , paralelleştirmek yerine GNU Parallel'i kullanırdım xargs:

cat url.lst |
  parallel -P0 -q curl -o /dev/null --silent --head --write-out '%{url_effective}: %{http_code}\n' > outfile

Bu özel durumda xargs, çıktı çok kısa olduğu için kullanımı güvenli olabilir , bu nedenle kullanımla ilgili sorun xargsdaha ziyade daha büyük bir şey yapmak için birisinin kodu değiştirmesi durumunda artık güvenli olmayacağıdır. Veya birisi bu soruyu okursa ve curlbaşka bir şeyle değiştirebileceğini düşünürse , bu da güvenli olmayabilir.

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.