我有一个保存在文本文件中的IP地址列表,我想使用子流程模块和for循环检查它们的代码编号(404,200,504,...)。对于一个IP地址,我的代码工作正常,但是当我尝试列表包含多个IP时,它会给我一些错误。
这是我的文本文件:
77.87.19.114
143.21.15.91
17.63.33.21
24.44.12.181
我使用的代码:
from subprocess import check_output
def ipcheck200(ip_list_file):
with open(ip_list_file) as f:
content = f.readlines()
for item in content:
# url generator for each ip
url = "http://" + item + "/"
#print(content[0])
# command generator for each ip
command = "python -c " + '"'
command += "import urllib ;"
command += "a = urllib.urlopen('%s') ;print(a.getcode())" % url
command += '"'
proc = check_output(command)
print(proc)
结果将是:
> Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
ipcheck200('test.txt')
File "C:\Users\XXXX\XXXX\XXXX\file.py", line 17, in ipcheck200
proc = check_output(command)
File "C:\Python27\lib\subprocess.py", line 573, in check_output
raise CalledProcessError(retcode, cmd, output=output)
CalledProcessError: Command 'python -c "import urllib ;a = urllib.urlopen('http://77.87.19.114
/') ;print(a.getcode())"' returned non-zero exit status 1
答案 0 :(得分:2)
当存在未处理的异常时,Python将以1
退出。
您没有错误处理;如果IP地址不存在,包含额外的空格,或者即使机器拒绝连接或只是超时,urllib.urlopen()
也会引发异常:
>>> urllib.urlopen('http://127.0.0.1:80')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python2.7/urllib.py", line 87, in urlopen
return opener.open(url)
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python2.7/urllib.py", line 213, in open
return getattr(self, name)(url)
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python2.7/urllib.py", line 350, in open_http
h.endheaders(data)
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python2.7/httplib.py", line 1053, in endheaders
self._send_output(message_body)
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python2.7/httplib.py", line 897, in _send_output
self.send(msg)
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python2.7/httplib.py", line 859, in send
self.connect()
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python2.7/httplib.py", line 836, in connect
self.timeout, self.source_address)
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python2.7/socket.py", line 575, in create_connection
raise err
IOError: [Errno socket error] [Errno 61] Connection refused
您的代码从文件中获取行而不进行进一步处理;它至少会在每一行附加一个换行符,所以你想去掉这一行:
for item in content:
item = item.strip()
您还在执行 sequence 中的所有子进程,因为check_output()
等待进程先完成;这比尝试在同一进程中运行此代码要慢。不要在这里重新发明多处理轮,而是使用multiprocessing
module代替:
from multiprocessing import Pool
import urllib
def check(ipaddress):
try:
response = urllib.urlopen('http://{}/'.format(url))
except IOError:
return 0 # connection unsuccessful (timeout, connection refused, etc)
return response.getcode()
if __name__ == '__main__':
p = Pool(10)
with open(ip_list_file) as f:
ipaddresses = [address.strip() for address in f if address.strip()]
print(p.map(check, ipaddresses))
此示例将使用10个子进程并行测试IP地址。