2016-04-04 2 views
-1

У меня есть список IP-адресов, сохраненных в текстовом файле, и я хочу проверить их код (404, 200, 504, ...) с помощью модуля подпроцесса и цикла for. для одного 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 yes Это нормально, я только что проверил. – 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 

Ваш код берет строки из файла без дополнительной обработки; он будет иметь символ новой строки, прикрепленную к каждой строке, по крайней мере, так что вы хотели бы полосу строку:

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

Вы также выполнение всех подпроцессов в последовательности, потому что 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-адреса параллельно.

+0

спасибо Я буду использовать это. – Uncle

+0

какой результат? для меня результат [0, 0, 0, 0]. но я уверен, что первый IP-адрес в порядке. – Uncle

+0

@PythonDeveloperDummy: у вас все еще есть исключения. Вы уверены, что эти IP-адреса доступны на порту 80? Попробуйте добавить журнал (где вы регистрируете 'repr()' каждого IP-адреса, к которому вы пытаетесь получить доступ), и регистрируйте все исключения, которые вы получаете. –

Смежные вопросы