73

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

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!

如果页面不存在(错误 402 或任何其他错误),我可以在该page = ...行中做些什么来确保我正在阅读的页面确实退出?

4

9 回答 9

134

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

对于 python 2.7.x,您可以使用httplib

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

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)

或者对于 2.7 和 3.x,您可以安装requests

import requests
response = requests.get('http://www.example.com')
if response.status_code == 200:
    print('Web site exists')
else:
    print('Web site does not exist') 
于 2013-05-27T18:11:34.077 回答
47

最好检查状态代码是否 < 400,就像在此处完成的那样。以下是状态码的含义(取自wikipedia):

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

如果你想检查页面是否存在并且不想下载整个页面,你应该使用Head Request

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

取自这个答案

如果您想下载整个页面,只需发出正常请求并检查状态码即可。使用请求的示例:

import requests

response = requests.get('http://google.com')
assert response.status_code < 400

另见类似主题:

希望有帮助。

于 2013-05-27T18:35:39.067 回答
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'

回答 unutbu 的评论:

因为默认处理程序处理重定向(300 范围内的代码),并且 100-299 范围内的代码表示成功,所以您通常只会看到 400-599 范围内的错误代码。 资源

于 2013-05-27T18:38:16.940 回答
8

@Adem Öztaş 提供了一个很好的答案,用于与httpliband一起使用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

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

我运行了上面的代码片段,并针对两个 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

最后一点:此功能也适用于资源主机不存在的情况。例如"http://abcdefghblahblah.com/test.mp4"将返回False.

于 2019-04-22T18:42:11.723 回答
5

代码:

a="http://www.example.com"
try:    
    print urllib.urlopen(a)
except:
    print a+"  site does not exist"
于 2013-10-04T10:39:49.483 回答
5

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

def uri_exists(url):
    r = requests.get(url, stream=True)
    if r.status_code == 200:
        return True
    else:
        return False
于 2020-04-24T08:50:22.950 回答
4
def isok(mypath):
    try:
        thepage = urllib.request.urlopen(mypath)
    except HTTPError as e:
        return 0
    except URLError as e:
        return 0
    else:
        return 1
于 2017-03-26T17:34:32.230 回答
1

试试这个::

import urllib2  
website='https://www.allyourmusic.com'  
try:  
    response = urllib2.urlopen(website)  
    if response.code==200:  
        print("site exists!")  
    else:  
        print("site doesn't exists!")  
except urllib2.HTTPError, e:  
    print(e.code)  
except urllib2.URLError, e:  
    print(e.args)  
于 2018-10-23T12:51:13.047 回答
1

我看到很多使用 的答案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

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

于 2021-09-01T15:50:18.563 回答