Python检查网站是否存在

Jam*_*len 50 html python urlopen

我想检查某个网站是否存在,这就是我正在做的事情:

user_agent = 'Mozilla/20.0.1 (compatible; MSIE 5.5; Windows NT)'
headers = { 'User-Agent':user_agent }
link = "http://www.abc.com"
req = urllib2.Request(link, headers = headers)
page = urllib2.urlopen(req).read() - ERROR 402 generated here!
Run Code Online (Sandbox Code Playgroud)

如果页面不存在(错误402,或其他任何错误),我该怎么做page = ...才能确保我正在阅读的页面退出?

Ade*_*taş 93

您可以使用HEAD请求而不是GET.它只会下载标题,但不会下载内容.然后,您可以从标题中检查响应状态.

import httplib
c = httplib.HTTPConnection('www.example.com')
c.request("HEAD", '')
if c.getresponse().status == 200:
   print('web site exists')
Run Code Online (Sandbox Code Playgroud)

或者你可以使用 urllib2

import urllib2
try:
    urllib2.urlopen('http://www.example.com/some_page')
except urllib2.HTTPError, e:
    print(e.code)
except urllib2.URLError, e:
    print(e.args)
Run Code Online (Sandbox Code Playgroud)

或者你可以使用 requests

import requests
request = requests.get('http://www.example.com')
if request.status_code == 200:
    print('Web site exists')
else:
    print('Web site does not exist') 
Run Code Online (Sandbox Code Playgroud)

  • 我不确定旧的`requests`模块是什么样的,但现在,`requests.head`是使用的函数,而不是`requests.get`. (4认同)
  • @AdemÖztaş,如果特定网站不可用则使用`requests`然后它会抛出`requests.exceptions.ConnectionError`. (4认同)
  • 请注意,即使URL存在,HEAD请求也可能失败.例如,亚马逊为其首页返回状态405(Method Not Allowed).在这种情况下可能需要额外的GET. (3认同)
  • 这个答案是错误的。网站返回的代码除了 200 个之外还有很多其他代码。此外,这不能处理长站点列表中出现的错误。 (3认同)

ale*_*cxe 38

最好检查状态代码是否<400,就像在这里完成的那样.以下是状态代码的含义(取自维基百科):

  • 1xx - 信息
  • 2xx - 成功
  • 3xx - 重定向
  • 4xx - 客户端错误
  • 5xx - 服务器错误

如果要检查页面是否存在而不想下载整个页面,则应使用头部请求:

import httplib2
h = httplib2.Http()
resp = h.request("http://www.google.com", 'HEAD')
assert int(resp[0]['status']) < 400
Run Code Online (Sandbox Code Playgroud)

取自这个答案.

如果要下载整个页面,只需发出正常请求并检查状态代码.使用请求的示例:

import requests

response = requests.get('http://google.com')
assert response.status_code < 400
Run Code Online (Sandbox Code Playgroud)

另见类似主题:

希望有所帮助.


小智 9

from urllib2 import Request, urlopen, HTTPError, URLError

user_agent = 'Mozilla/20.0.1 (compatible; MSIE 5.5; Windows NT)'
headers = { 'User-Agent':user_agent }
link = "http://www.abc.com/"
req = Request(link, headers = headers)
try:
        page_open = urlopen(req)
except HTTPError, e:
        print e.code
except URLError, e:
        print e.reason
else:
        print 'ok'
Run Code Online (Sandbox Code Playgroud)

回答unutbu的评论:

由于默认处理程序处理重定向(300范围内的代码),并且100-299范围内的代码表示成功,因此通常只能看到400-599范围内的错误代码. 资源


Ger*_*nno 7

我看到很多答案都使用requests.get,但我建议您仅使用这个解决方案,requests.head它更快,对网络服务器也更好,因为它也不需要发回正文。

import requests

def check_url_exists(url: str):
    """
    Checks if a url exists
    :param url: url to check
    :return: True if the url exists, false otherwise.
    """
    return requests.head(url, allow_redirects=True).status_code == 200
Run Code Online (Sandbox Code Playgroud)

响应 HEAD 请求的 HTTP 标头中包含的元信息应与响应 GET 请求而发送的信息相同。


Raj*_*Raj 5

码:

a="http://www.example.com"
try:    
    print urllib.urlopen(a)
except:
    print a+"  site does not exist"
Run Code Online (Sandbox Code Playgroud)


Max*_*eld 5

@AdemÖzta?提供了一个很好的答案,可与httplib和一起使用urllib2。对于requests,如果问题仅是关于资源存在的,则在存在大量资源的情况下可以改善答案。

先前的答案requests建议如下所示:

def uri_exists_get(uri: str) -> bool:
    try:
        response = requests.get(uri)
        try:
            response.raise_for_status()
            return True
        except requests.exceptions.HTTPError:
            return False
    except requests.exceptions.ConnectionError:
        return False
Run Code Online (Sandbox Code Playgroud)

requests.get尝试一次提取整个资源,因此对于大型媒体文件,以上代码段将尝试将整个媒体提取到内存中。为了解决这个问题,我们可以流式传输响应。

def uri_exists_stream(uri: str) -> bool:
    try:
        with requests.get(uri, stream=True) as response:
            try:
                response.raise_for_status()
                return True
            except requests.exceptions.HTTPError:
                return False
    except requests.exceptions.ConnectionError:
        return False
Run Code Online (Sandbox Code Playgroud)

我用两个Web资源附带的计时器运行了以上代码片段:

1)http://bbb3d.renderfarming.net/download.html,非常浅的html页面

2)http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4,大小合适的视频文件

计时结果如下:

uri_exists_get("http://bbb3d.renderfarming.net/download.html")
# Completed in: 0:00:00.611239

uri_exists_stream("http://bbb3d.renderfarming.net/download.html")
# Completed in: 0:00:00.000007

uri_exists_get("http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4")
# Completed in: 0:01:12.813224

uri_exists_stream("http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4")
# Completed in: 0:00:00.000007
Run Code Online (Sandbox Code Playgroud)

最后一点:如果资源主机不存在,此功能也可以使用。例如"http://abcdefghblahblah.com/test.mp4"将返回False


rus*_*sty 5

您可以简单地使用stream不下载完整文件的方法。与最新的 Python3 一样,您不会获得 urllib2。最好使用经过验证的请求方法。这个简单的功能将解决您的问题。

def uri_exists(url):
    r = requests.get(url, stream=True)
    if r.status_code == 200:
        return True
    else:
        return False
Run Code Online (Sandbox Code Playgroud)