2016-04-04 6 views
-1

私はテキストファイルに保存されたIPアドレスのリストを持っており、サブプロセスモジュールとforループを使ってコード番号(404,200,504、...)をチェックしたいと思います。 1つのIPアドレスのために私のコードは正常に動作しますが、リストに複数のIPが含まれていれば、いくつかのエラーが出ます。サブプロセスモジュールがforループで複数のコマンドを実行しないのはなぜですか?

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 
+1

URLの最後に '/'( 'http://77.87.19.114 /')の直前にスペースがありますが、それは正常ですか? 入力を確認してください。 – Morb

+0

forループなしではどうなりますか? –

+0

@MorbはいそれはOKです、ただチェックしました。 – Uncle

答えて

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 

あなたのコードは、さらに処理せずに、ファイルから行を取ります。それは非常に少なくとも、各ラインに添付改行を持っていますので、あなたはストリップラインにしたいと思います。また、check_output()待機しているため、シーケンス内のすべてのサブプロセスを実行している

for item in content: 
    item = item.strip() 

プロセスが最初に完了するために。これは同じプロセスでこのコードを実行しようとするよりも遅くなるでしょう。ここでは、マルチプロセッシングホイールを再発明しないで、代わりに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)) 

このサンプルでは、​​並行して、IPアドレスをテストするために10個のサブプロセスを使用します。

+0

ありがとう、私はこれを使用します。 – Uncle

+0

結果はどうですか?私の結果は[0、0、0、0]です。私は最初のIPアドレスがOKだと確信しています。 – Uncle

+0

@PythonDeveloperDummy:それでも例外が発生します。それらのIPアドレスがポート80に到達可能であることは確かですか?ログに(アクセスしようとする各IPアドレスの 'repr()'を記録する)ログを追加して、あなたが取得した例外もログに記録してみてください。 –

関連する問題