สคริปต์เพื่อรับรหัสสถานะ HTTP ของรายการ URL?


89

ฉันมีรายการ URL ที่ต้องตรวจสอบเพื่อดูว่ายังใช้งานได้หรือไม่ ฉันต้องการเขียนสคริปต์ทุบตีที่ทำเพื่อฉัน

ฉันต้องการรหัสสถานะ HTTP ที่ส่งคืนเท่านั้นเช่น 200, 404, 500 เป็นต้น ไม่มีอะไรมาก

แก้ไขโปรดทราบว่ามีปัญหาหากหน้าระบุว่า "ไม่พบ 404" แต่ส่งกลับข้อความ 200 OK เป็นเว็บเซิร์ฟเวอร์ที่กำหนดค่าไม่ถูกต้อง แต่คุณอาจต้องพิจารณากรณีนี้

สำหรับข้อมูลเพิ่มเติมโปรดดูที่ตรวจสอบว่า URL ไปยังหน้าที่มีข้อความ "404" หรือไม่


2
เพื่อความเป็นธรรม "ข้อบกพร่อง" ของสคริปต์ของฉันคือเมื่อเซิร์ฟเวอร์ส่งคืนรหัส HTTP 200 เท่านั้น แต่ข้อความเนื้อหาระบุว่า "ไม่พบ 404" ซึ่งเป็นเว็บเซิร์ฟเวอร์ที่ทำงานผิดปกติ
ฟิล

2
สถานะการออกของ wget จะเป็น 0 ถ้ารหัสตอบกลับคือ 200, 8 ถ้า 404, 4 ถ้า 302 ... คุณสามารถใช้ $? เพื่อเข้าถึงสถานะการออกของคำสั่งก่อนหน้า
Casey Watson

คำตอบ:


198

Curl มีตัวเลือกเฉพาะ--write-outสำหรับสิ่งนี้:

$ curl -o /dev/null --silent --head --write-out '%{http_code}\n' <url>
200
  • -o /dev/null พ่นเอาท์พุทตามปกติออกไป
  • --silent โยนมิเตอร์ความคืบหน้าออกไป
  • --head สร้างคำขอ HEAD HTTP แทน GET
  • --write-out '%{http_code}\n' พิมพ์รหัสสถานะที่ต้องการ

หากต้องการสรุปสิ่งนี้ในสคริปต์ Bash ที่สมบูรณ์:

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

(ผู้อ่าน Eagle-eyed จะสังเกตเห็นว่าสิ่งนี้ใช้กระบวนการ curl หนึ่งรายการต่อหนึ่ง URL ซึ่งกำหนดบทลงโทษการเชื่อมต่อทางแยกและ TCP มันจะเร็วกว่าถ้า URL หลายรายการรวมกันใน curl เดียว แต่ไม่มีพื้นที่สำหรับเขียนการทำซ้ำที่น่ากลัว ตัวเลือกที่ curl ต้องการในการทำสิ่งนี้)


ดีมาก. ฉันสามารถรันคำสั่งนั้นกับทุก url ในไฟล์ของฉันได้หรือไม่?
Manu

1
@Manu: ใช่ฉันได้แก้ไขคำตอบของฉันเพื่อแสดงวิธีหนึ่งที่เป็นไปได้ในการตัดคำสั่ง curl ถือว่า url-list.txt มีหนึ่ง URL ต่อบรรทัด
ฟิลิป

1
ฉันไม่รู้ว่าทำไมสคริปต์จากด้านบน andswer ทำให้ฉันได้รับ 000 ในผลลัพธ์เสมอ แต่เมื่อฉันรันคำสั่งเพียงครั้งเดียวโดยไม่ต้องวนซ้ำมันทำงาน ...
Karol F

1
@KarolFiturski ฉันมีปัญหาเดียวกัน (ซึ่งคุณอาจได้รับการแก้ไขแล้ว แต่ในกรณีที่มีคนสะดุดในเรื่องนี้ ... http://example.com/\rเมื่อผ่านวง
Jordan Robinson

1
ฉันมีปัญหานี้และฉันสามารถแก้ไขได้โดยเปลี่ยนบรรทัดที่ลงท้ายจากประเภท Windows เป็นประเภท Linux
Tristan

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

พิมพ์เฉพาะรหัสสถานะสำหรับคุณ


9
+1 แสดงรหัสหลายรายการเมื่อ URL ถูกเปลี่ยนเส้นทางโดยแต่ละรายการจะขึ้นบรรทัดใหม่
Ashfame

ต้องกำจัด - สไปเดอร์เพื่อให้มันทำงานกับคำขอที่ฉันพยายามทำ แต่ได้ผล
amitavk

30

ขยายคำตอบที่ Phil การเพิ่มความเท่าเทียมกันนั้นไม่ใช่เรื่องง่ายในการทุบตีหากคุณใช้ xargs สำหรับการโทร

นี่คือรหัส:

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

-n1 : ใช้เพียงค่าเดียว (จากรายการ) เป็นอาร์กิวเมนต์สำหรับการเรียก curl

-P10 : รักษา 10 กระบวนการ curl ไว้ตลอดเวลา (เช่น 10 การเชื่อมต่อแบบขนาน)

ตรวจสอบwrite_outพารามิเตอร์ในคู่มือของ curl เพื่อดูข้อมูลเพิ่มเติมที่คุณสามารถดึงออกมาได้โดยใช้ (ครั้ง ฯลฯ )

เผื่อว่าจะช่วยใครได้นี่คือสายที่ฉันใช้อยู่:

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

เพียงแค่ส่งออกข้อมูลจำนวนมากในไฟล์ csv ที่สามารถนำเข้าสู่เครื่องมือสำนักงานใดก็ได้


2
Parallelism อินพุตไฟล์และ csv สิ่งที่ฉันกำลังมองหา
Agey

ยอดเยี่ยมทำให้วันของฉัน
xlttj

มันยอดเยี่ยมมากสำหรับสิ่งที่ฉันกำลังมองหาขอบคุณครับ คำถามหนึ่งจะรวมชื่อหน้าของเพจในผลลัพธ์ csv ได้อย่างไร
MitchellK

@estani - stackoverflow.com/users/1182464/estaniจะรวมชื่อหน้าของเพจลงในไฟล์. csv ได้อย่างไร ขออภัยสำหรับการโพสต์ใหม่ลืมแท็กคุณเพื่อให้คุณได้รับการแจ้งเตือนเกี่ยวกับคำถามนี้ ขอบคุณมาก.
MitchellK

@MitchellK นี่ไม่ได้จัดการเนื้อหาของการโทร http เลย หาก "ชื่อหน้า" (อะไรก็ได้) อยู่ใน url คุณสามารถเพิ่มได้ หากไม่เป็นเช่นนั้นคุณต้องแยกวิเคราะห์ทั้งหน้าเพื่อแยก "ชื่อเรื่อง" ของมัน (สมมติว่าคุณหมายถึงเพจ html ที่เรียกโดย http) มองหาคำตอบอื่น ๆ ที่ stack overflow หรือถามคำถามเฉพาะนั้น
estani

17

สิ่งนี้ขึ้นอยู่กับที่มีอยู่อย่างแพร่หลายwgetในปัจจุบันเกือบทุกที่แม้กระทั่งบน Alpine Linux

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

คำอธิบายมีดังต่อไปนี้:

--quiet

ปิดเอาต์พุตของ Wget

ที่มา - wget man pages

--spider

[... ] จะไม่ดาวน์โหลดหน้าเว็บเพียงตรวจสอบว่ามีอยู่ [... ]

ที่มา - wget man pages

--server-response

พิมพ์ส่วนหัวที่ส่งโดยเซิร์ฟเวอร์ HTTP และการตอบกลับที่ส่งโดยเซิร์ฟเวอร์ FTP

ที่มา - wget man pages

สิ่งที่พวกเขาไม่ได้พูดถึง--server-responseคือเอาต์พุตส่วนหัวเหล่านั้นถูกพิมพ์เป็นข้อผิดพลาดมาตรฐาน (sterr)ดังนั้นจึงจำเป็นต้องเปลี่ยนเส้นทางไปยัง stdin

เอาต์พุตที่ส่งไปยังอินพุตมาตรฐานเราสามารถไพพ์awkเพื่อแยกรหัสสถานะ HTTP รหัสนั้นคือ:

  • $2กลุ่มอักขระที่สอง ( ) ที่ไม่ว่างเปล่า:{$2}
  • ในบรรทัดแรกของส่วนหัว: NR==1

และเพราะเราต้องการที่จะพิมพ์ {print $2}...

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

1
ฉันใช้อันนี้กับ2>&1 | head -1 | awk '{ print $2 }'
Evhz

7

ใช้curlเพื่อดึงข้อมูลส่วนหัว HTTP เท่านั้น (ไม่ใช่ทั้งไฟล์) และแยกวิเคราะห์:

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

curl บอกฉัน 200 เมื่อ wget พูดว่า 404 ... :(
Manu

-Iสาเหตุธงขดที่จะทำให้การร้องขอ HTTP HEAD ซึ่งจะถือว่าแยกต่างหากจากปกติ HTTP GET โดยบางเซิร์ฟเวอร์และทำให้สามารถคืนค่าที่แตกต่างกัน คำสั่งควรยังคงใช้งานได้หากไม่มี
lambshaanxy

4

wget -S -i *file* จะทำให้คุณได้รับส่วนหัวจากแต่ละ URL ในไฟล์

กรองgrepสำหรับรหัสสถานะโดยเฉพาะ


1

ฉันพบเครื่องมือ "webchk" ที่เขียนด้วย Python ส่งคืนรหัสสถานะสำหรับรายการ URL https://pypi.org/project/webchk/

ผลลัพธ์มีลักษณะดังนี้:

▶ 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)

หวังว่าจะช่วยได้!


0

เนื่องจากhttps://mywiki.wooledge.org/BashPitfalls#Non-atomic_writes_with_xargs_-P (ผลลัพธ์จากงานคู่ขนานที่มีxargsความเสี่ยงผสมกัน) ฉันจะใช้ GNU Parallel แทนxargsการขนาน:

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

ในกรณีนี้อาจใช้งานได้อย่างปลอดภัยxargsเนื่องจากเอาต์พุตสั้นมากดังนั้นปัญหาในการใช้งานxargsจึงค่อนข้างที่หากมีคนเปลี่ยนรหัสเพื่อทำสิ่งที่ใหญ่กว่าในภายหลังก็จะไม่ปลอดภัยอีกต่อไป หรือถ้ามีคนอ่านคำถามนี้และคิดว่าเขาสามารถแทนที่curlด้วยสิ่งอื่นได้นั่นก็อาจไม่ปลอดภัยเช่นกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.