Was ist der beste Weg, um einen HTTP-Antwortcode von einer URL zu erhalten?

80

Ich suche nach einer schnellen Möglichkeit, einen HTTP-Antwortcode von einer URL (z. B. 200, 404 usw.) abzurufen. Ich bin mir nicht sicher, welche Bibliothek ich verwenden soll.

alexwlchan
quelle

Antworten:

98

Aktualisieren Sie mit der wundervollen Anforderungsbibliothek . Beachten Sie, dass wir die HEAD-Anforderung verwenden, die schneller als eine vollständige GET- oder POST-Anforderung erfolgen sollte.

import requests
try:
    r = requests.head("https://stackoverflow.com")
    print(r.status_code)
    # prints the int of the status code. Find more at httpstatusrappers.com :)
except requests.ConnectionError:
    print("failed to connect")
Gourneau
quelle
Anfragen sind viel besser als urllib2, für einen solchen Link: dianping.com/promo/208721#mod=4 , urllib2 gibt mir eine 404 und Anfragen geben eine 200, genau wie ich es von einem Browser bekomme.
WKPlus
5
httpstatusrappers.com ... super !! Mein Code ist auf diesem Lil Jon Status, mein Sohn!
tmthyjames
1
Dies ist die beste Lösung. Viel besser als alle anderen.
Awn
@WKPlus für den Datensatz, requestsgibt jetzt 403für Ihren Link, obwohl es noch im Browser funktioniert.
Dennis Golomazov
2
@ Gourneau Ha! Das war nicht das, was ich mit meinem Kommentar beabsichtigt hatte, ich denke, es war vollkommen in Ordnung, und in diesem Zusammenhang sollten die Leute versuchen zu verstehen, warum es im Browser "nur funktioniert", aber einen 403-Code zurückgeben, wenn er tatsächlich derselbe ist an beiden Orten passiert etwas.
Seeleute
65

Hier ist eine Lösung, die httplibstattdessen verwendet.

import httplib

def get_status_code(host, path="/"):
    """ This function retreives the status code of a website by requesting
        HEAD data from the host. This means that it only requests the headers.
        If the host cannot be reached or something else goes wrong, it returns
        None instead.
    """
    try:
        conn = httplib.HTTPConnection(host)
        conn.request("HEAD", path)
        return conn.getresponse().status
    except StandardError:
        return None


print get_status_code("stackoverflow.com") # prints 200
print get_status_code("stackoverflow.com", "/nonexistant") # prints 404
Evan Fosmark
quelle
14
+1 für HEAD-Anforderung - Sie müssen nicht die gesamte Entität für eine Statusprüfung abrufen.
Ben Blank
7
Obwohl Sie diesen exceptBlock wirklich auf mindestens beschränken sollten, StandardErrordamit Sie Dinge wie nicht falsch fangen KeyboardInterrupt.
Ben Blank
3
Ich habe mich gefragt, ob HEAD-Anfragen zuverlässig sind. Weil Websites die HEAD-Methode möglicherweise nicht (ordnungsgemäß) implementiert haben, was zu Statuscodes wie 404, 501 oder 500 führen kann. Oder bin ich paranoid?
Blaise
2
Wie würde man dies dazu bringen, 301s zu folgen?
Randall Hunt
2
@Blaise Wenn eine Website nicht HEAD - Anfragen erlaubt dann eine HEAD - Anfrage durchführen sollte in einem 405 Fehler. Versuchen Sie als Beispiel, es auszuführen curl -I http://www.amazon.com/.
Nick
24

Sie sollten urllib2 wie folgt verwenden:

import urllib2
for url in ["http://entrian.com/", "http://entrian.com/does-not-exist/"]:
    try:
        connection = urllib2.urlopen(url)
        print connection.getcode()
        connection.close()
    except urllib2.HTTPError, e:
        print e.getcode()

# Prints:
# 200 [from the try block]
# 404 [from the except block]
RichieHindle
quelle
3
Dies ist keine gültige Lösung, da urllib2 Weiterleitungen folgt, sodass Sie keine 3xx-Antworten erhalten.
Sorin
1
@sorin: Das hängt davon ab - vielleicht möchten Sie Weiterleitungen folgen. Vielleicht möchten Sie die Frage stellen: "Wenn ich diese URL mit einem Browser besuchen würde, würde sie Inhalt anzeigen oder einen Fehler geben?" In diesem Fall, wenn ich geändert , http://entrian.com/um http://entrian.com/blogin meinem Beispiel würde die resultierenden 200 korrekt sein , obwohl es eine Umleitung an beteiligt http://entrian.com/blog/( man beachte den Schrägstrich).
RichieHindle
8

Für diejenigen, die Python3 und höher verwenden, gibt es in Zukunft einen weiteren Code, um den Antwortcode zu finden.

import urllib.request

def getResponseCode(url):
    conn = urllib.request.urlopen(url)
    return conn.getcode()
Nickanor
quelle
2
Dies löst einen HTTPError für Statuscodes wie 404, 500 usw. aus
Niklas R
3

Die urllib2.HTTPErrorAusnahme enthält keine getcode()Methode. Verwenden Sie codestattdessen das Attribut.

Martijn Pieters
quelle
2
Für mich mit Python 2.6.
RichieHindle
2

Adressierung des Kommentars von @Niklas R zur Antwort von @ nickanor:

from urllib.error import HTTPError
import urllib.request

def getResponseCode(url):
    try:
        conn = urllib.request.urlopen(url)
        return conn.getcode()
    except HTTPError as e:
        return e.code
EL
quelle
0

Hier ist eine httplibLösung, die sich wie urllib2 verhält. Sie können ihm einfach eine URL geben und es funktioniert einfach. Sie müssen sich nicht um die Aufteilung Ihrer URLs in Hostname und Pfad kümmern. Diese Funktion macht das schon.

import httplib
import socket
def get_link_status(url):
  """
    Gets the HTTP status of the url or returns an error associated with it.  Always returns a string.
  """
  https=False
  url=re.sub(r'(.*)#.*$',r'\1',url)
  url=url.split('/',3)
  if len(url) > 3:
    path='/'+url[3]
  else:
    path='/'
  if url[0] == 'http:':
    port=80
  elif url[0] == 'https:':
    port=443
    https=True
  if ':' in url[2]:
    host=url[2].split(':')[0]
    port=url[2].split(':')[1]
  else:
    host=url[2]
  try:
    headers={'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:26.0) Gecko/20100101 Firefox/26.0',
             'Host':host
             }
    if https:
      conn=httplib.HTTPSConnection(host=host,port=port,timeout=10)
    else:
      conn=httplib.HTTPConnection(host=host,port=port,timeout=10)
    conn.request(method="HEAD",url=path,headers=headers)
    response=str(conn.getresponse().status)
    conn.close()
  except socket.gaierror,e:
    response="Socket Error (%d): %s" % (e[0],e[1])
  except StandardError,e:
    if hasattr(e,'getcode') and len(e.getcode()) > 0:
      response=str(e.getcode())
    if hasattr(e, 'message') and len(e.message) > 0:
      response=str(e.message)
    elif hasattr(e, 'msg') and len(e.msg) > 0:
      response=str(e.msg)
    elif type('') == type(e):
      response=e
    else:
      response="Exception occurred without a good error message.  Manually check the URL to see the status.  If it is believed this URL is 100% good then file a issue for a potential bug."
  return response
Sam Gleske
quelle
1
Ich bin mir nicht sicher, warum dies ohne Feedback abgelehnt wurde. Es funktioniert mit HTTP- und HTTPS-URLs. Es verwendet die HEAD-Methode von HTTP.
Sam Gleske