Python中的HTTP检查

3 投票
4 回答
704 浏览
提问于 2025-04-15 14:41

我在这里学习Python,我想检查一下我的本地网络上有没有人正在运行网页服务器。我用这段代码,但在控制台上出现了很多错误。

#!/usr/bin/env python

import httplib
last = 1
while last <> 255:
        url = "10.1.1." + "last"
        connection = httplib.HTTPConnection("url", 80)
        connection.request("GET","/")
        response = connection.getresponse()
        print (response.status)
        last = last + 1

4 个回答

1

把变量名 lasturl 的引号去掉。因为在Python中,它把带引号的内容当作字符串,而不是变量。试试这样:

#!/usr/bin/env python

import httplib
last = 1
while last <> 255:
        url = "10.1.1.%d" % last
        connection = httplib.HTTPConnection(url, 80)
        connection.request("GET","/")
        response = connection.getresponse()
        print (response.status)
        last = last + 1
2

正如所提到的,你在基本的引号使用上有些问题。但更根本的是:

  1. 你没有使用Python特有的写法来处理事情,而是用简单的命令式代码来编写。这当然没问题,但下面是一些更有趣(也更好的)表达方式的例子。
  2. 你需要明确设置超时时间,否则会花费很长时间。
  3. 你需要使用多线程,否则也会花费很长时间。
  4. 你需要处理各种常见的异常类型,否则你的代码会崩溃:在真实的网络服务器上,连接会在多种情况下失败(包括超时)。
  5. 10.1.1.*只是“本地”服务器的一种可能的设置。RFC 1918规定了“本地”地址范围是10.0.0.0 - 10.255.255.255,172.16.0.0 - 172.31.255.255,以及192.168.0.0 - 192.168.255.255。在你的“本地”网络中,通用的响应者检测是一个难题。
  6. 网络服务器(尤其是本地服务器)通常运行在80以外的其他端口上(特别是8000、8001或8080)。
  7. 一般网络服务器、DNS等的复杂性使得你可能在不同的时间遇到各种超时行为(并且受到最近操作的影响)。

下面是一些示例代码,帮助你入门,基本上解决了上述所有问题,除了第(5)点,我假设那超出了问题的范围。

顺便说一下,我打印了返回网页的大小,因为这简单地表示了网页的内容。示例IP返回了各种Yahoo的资源。

import urllib
import threading
import socket

def t_run(thread_list, chunks):
    t_count = len(thread_list)
    print "Running %s jobs in groups of %s threads" % (t_count, chunks)
    for x in range(t_count / chunks + 1):
        i = x * chunks
        i_c = min(i + chunks, t_count)
        c = len([t.start() for t in thread_list[i:i_c]])
        print "Started %s threads for jobs %s...%s" % (c, i, i_c - 1)
        c = len([t.join() for t in thread_list[i:i_c]])
        print "Finished %s threads for job index %s" % (c, i)

def url_scan(ip_base, timeout=5):
    socket.setdefaulttimeout(timeout)
    def f(url):
        # print "-- Trying (%s)" % url
        try:
            # the print will only complete if there's a server there
            r = urllib.urlopen(url)
            if r:
                print "## (%s) got %s bytes" % (url, len(r.read()))
            else:
                print "## (%s) failed to connect" % url
        except IOError, msg:
            # these are just the common cases
            if str(msg)=="[Errno socket error] timed out":
                return
            if str(msg)=="[Errno socket error] (10061, 'Connection refused')":
                return
            print "## (%s) got error '%s'" % (url, msg)
            # you might want 8000 and 8001, too
            return [threading.Thread(target=f, 
                             args=("http://" + ip_base + str(x) + ":" + str(p),)) 
                    for x in range(255) for p in [80, 8080]]

# run them (increase chunk size depending on your memory)
# also, try different timeouts
t_run(url_scan("209.131.36."), 100)
t_run(url_scan("209.131.36.", 30), 100)
5

我建议把这个 while 循环改成更常用的 for 循环,并且处理一下可能出现的错误:

#!/usr/bin/env python

import httplib
import socket


for i in range(1, 256):
    try:
        url = "10.1.1.%d" % i
        connection = httplib.HTTPConnection(url, 80)
        connection.request("GET","/")
        response = connection.getresponse()
        print url + ":", response.status
    except socket.error:
        print url + ":", "error!"

想知道怎么给这个加个超时,这样检查每个服务器就不会花太长时间,可以看看 这里

撰写回答