Python脚本:如何在不下载整个网页的情况下判断网页是否存在?

18

我想编写一个脚本来测试网页是否存在,如果能够在不下载整个页面的情况下进行检查,那就太好了。

这是我的起点,我看到了多个例子都是以相同的方式使用httplib的,但是我检查的每个站点都只返回false。

import httplib
from httplib import HTTP
from urlparse import urlparse

def checkUrl(url):
    p = urlparse(url)
    h = HTTP(p[1])
    h.putrequest('HEAD', p[2])
    h.endheaders()
    return h.getreply()[0] == httplib.OK

if __name__=="__main__":
    print checkUrl("http://www.stackoverflow.com") # True
    print checkUrl("http://stackoverflow.com/notarealpage.html") # False

有什么想法吗?

编辑

有人建议使用这个,但他们的帖子被删除了.. urllib2是否避免下载整个页面?

import urllib2

try:
    urllib2.urlopen(some_url)
    return True
except urllib2.URLError:
    return False

2
第二个例子实际上是存在的 :) http://stackoverflow.com/notarealpage.html - Gabi Purcaru
我对重复另一个用户的答案感到内疚,所以你应该查看这个问题:https://dev59.com/5k_Sa4cB1Zd3GeqP8QLX。需要提醒的是,尽管这个问题的措辞略有不同,但由于与其他问题非常相似,可能会被标记为重复。 - cwallenpoole
6
不行。响应中存在一个实体,但状态代码很明确:未找到。假定404不能表达任何信息(或必须具有默认的“无聊”错误消息)是一个误解。它只是意味着你要查找的资源不存在,并且结果显示SO已经很好地实现了此功能,因此它提供了一个可读的人类描述(说“页面未找到”...)。 - Bruno
请注意,一些Web服务器(例如我的情况下的IIS)不支持HEAD,并且可能会响应401而不是200,但使用GET返回200。在这种情况下,最快的方法是使用requests的stream=True进行部分块下载。它将执行适当的GET而不下载文件。 - Florent Thiery
4个回答

25
这个怎么样?
import httplib
from urlparse import urlparse

def checkUrl(url):
    p = urlparse(url)
    conn = httplib.HTTPConnection(p.netloc)
    conn.request('HEAD', p.path)
    resp = conn.getresponse()
    return resp.status < 400

if __name__ == '__main__':
    print checkUrl('http://www.stackoverflow.com') # True
    print checkUrl('http://stackoverflow.com/notarealpage.html') # False

这将发送一个HTTP HEAD请求,并在响应状态码<400时返回True。

  • 请注意,StackOverflow的根路径返回的是重定向(301),而不是200 OK。

4
为了兼容Python3,需要做出一些更改。将import urllib.parse as urlparse和import httplib2添加到代码中。HTTPConnection替换为HTTPConnectionWithTimeout。urlparse替换为urlparse.urlparse。 - Kabira K
可能会返回HTTP 401或403,但URL可能存在。 - Raj

18

使用requests,这很简单:

import requests

ret = requests.head('http://www.example.com')
print(ret.status_code)

这只是加载网站头部的过程。要测试它是否成功,可以检查结果status_code。或使用raise_for_status方法,如果连接失败会触发一个Exception异常。


6
这个怎么样?
import requests

def url_check(url):
    #Description

    """Boolean return - check to see if the site exists.
       This function takes a url as input and then it requests the site 
       head - not the full html and then it checks the response to see if 
       it's less than 400. If it is less than 400 it will return TRUE 
       else it will return False.
    """
    try:
            site_ping = requests.head(url)
            if site_ping.status_code < 400:
                #  To view the return status code, type this   :   **print(site.ping.status_code)** 
                return True
            else:
                return False
    except Exception:
        return False

你应该添加代码描述。这将有助于查看此答案的未来访问者,也将有助于原始问题的提出者。 - BusyProgrammer
404 不会抛出异常。需要在 else 中返回 False。 - Kabira K

-2
你可以尝试。
import urllib2

try:
    urllib2.urlopen(url='https://someURL')
except:
    print("page not found")

3
urlopen函数会下载整个页面,这是OP试图避免的。 - Darrick Herwehe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接