2016-06-18 4 views
0

Я работаю над сценарием Python3, который делает следующее:«объект„NoneType“не subscriptable» ИЛИ «KeyError:» с openpyxl и ipwhois

  1. Открыть файл первенствовать в рабочем каталоге
  2. Выберите первый лист в Excel файл
  3. Выберите все данные в третьем столбце (в этом случае спектр IP-адреса)
  4. перебирать все IP-адрес и вызвать WHOIS API для каждого
  5. магазина результаты для каждого IP-адреса переменный (.json)
  6. Анализировать через результат ищет имя, IP-диапазон, контактную информацию
  7. Написать значение от 6 выше новых строк в Excel файл
  8. Сохраните файл Excel с новым именем в текущий каталог

В текущем документе есть список из 427 уникальных IP-адресов, а результаты whois api для имени RIPE уникальны (иногда в пределах одного ответа). Чтобы учесть это, я повторил каждое имя RIPE для получения вторичных наборов данных в списке ['contact']. Это работает отлично, пока список контактов содержит значения, которые я хочу. Если это не так, я получаю сообщение об ошибке NoneType. Я попытался построить превентивную логику вокруг этого с помощью оператора if, где result == None назначил мои переменные значением «NULL», но затем я получаю исключение KeyError в имени RIPE. Я застрял и нуждаюсь в вашей помощи. Вот копия моего кода:

import openpyxl 

from pprint import pprint 
from ipwhois import IPWhois 

wb = openpyxl.load_workbook('Abuse Log with Notes FWC 2016-06-09.xlsx')#change name here to file to be used 
sheet = wb.get_sheet_by_name('Sheet1') #get first sheet in workbook 

#Add new column headings for API results 
sheet['E1'] = 'HOST NAME' 
sheet['F1'] = 'HOST COUNTRY' 
sheet['G1'] = 'IP START' 
sheet['H1'] = 'IP END' 
sheet['I1'] = 'HOST EMAIL' 
sheet['J1'] = 'HOST PHONE' 
sheet['K1'] = 'HOST ADDRESS' 

#Store all start range IP's for Amazon in one list variable 
AmazonStartIPs = [ 
    '54.64.0.0', '54.160.0.0','54.144.0.0', 
    '52.64.0.0','54.208.0.0','54.192.0.0', 
    '54.240.0.0','54.224.0.0','54.72.0.0', 
    '54.176.0.0','52.32.0.0','52.0.0.0', 
    '52.192.0.0','52.84.0.0','53.32.0.0'] 

def checkForAmazon(): 
    if StartAddress in AmazonStartIPs: 
     Name = 'Amazon Web Services - Elastic Compute Cloud' 
     CountryCode = 'US' 
     AbuseEmail = '[email protected]' 
     AbusePhone = '+1-206-266-4064' 
     AbuseAddress = ['410 Terry Avenue','North Seattle', 'WA', '98109-5210','UNITED STATES'] 

iterateColumn = sheet.columns[2]#get all cell values in column C 
currentRowIndex = 2 

for Address in iterateColumn[1:5]:#test range 1:5 to reduce API load 
    ip_address = Address.value#set var to value of item in iterateColumn 
     IP = IPWhois(ip_address)#store whois call in var of IP 
     results = IP.lookup_rdap(depth=1)#call whois and store .json results 

     Name = results['network']['name']#set name to IP Host name 
     Name=''.join(Name)#formatting for excel 

     CountryCode = results['asn_country_code']#var for country code 
     CountryCode=''.join(CountryCode) 

     StartAddress = results['network']['start_address']#var for IP range Start 
     StartAddress=''.join(StartAddress) 

     EndAddress = results['network']['end_address']#var for IP range End 
     EndAddress = ''.join(EndAddress) 

     #write values above to iterable rows in spreadsheet 
     sheet.cell(row = currentRowIndex, column = 5).value = Name 
     sheet.cell(row = currentRowIndex, column = 6).value = CountryCode 
     sheet.cell(row = currentRowIndex, column = 7).value = StartAddress 
     sheet.cell(row = currentRowIndex, column = 8).value = EndAddress 

     for key in results['objects']:#get unique key values in results object 
     r = key#store as var of r to prevent having to call by ripe name 

     AbuseEmail = results['objects'][r]['contact']['email'][0]['value'] 
     if results['objects'][r]['contact']['email'] == None: 
     AbuseEmail = 'NULL' 
     elif results['objects'] is None: 
     AbuseEmail = 'NULL' 

     sheet.cell(row = currentRowIndex, column = 9).value = AbuseEmail 
     AbuseEmail = ''.join(AbuseEmail) 

     if results['objects'][r]['contact']['phone'] == None: 
     AbusePhone = 'NULL' 
     else: 
     AbusePhone = results['objects'][r]['contact']['phone'][0]['value'] 

     sheet.cell(row=currentRowIndex, column = 10).value = AbusePhone 
     AbusePhone = ''.join(AbusePhone) 

     if results['objects'][r]['contact']['address'] == None: 
     AbuseAddress = 'NULL' 
     else: 
     AbuseAddress = results['objects'][r]['contact']['address'][0]['value'] 

     sheet.cell(row=currentRowIndex, column = 11).value = AbuseAddress 
     AbuseAddress =''.join(AbuseAddress) 

     checkForAmazon() 

     currentRowIndex += 1 


rowsUpdated = sheet.max_row 
print('{} records have been updated.'.format(rowsUpdated)) 

wb.save('ABUSE_IP_LOG_HOST_DATA.xlsx') 
+1

Используйте 'try' /' except' условие для каждого где может быть ключевая ошибка. – MattDMo

+0

Я добавил try/except for all cases и решил проблему. Спасибо, MattDMo! – Fergus

+1

Я предлагаю вам разделить код, который выполняет поиск, и преобразует его в полезную форму из кода, который добавляет его на рабочий лист. 'Sheet.cell (...)', поскольку вы используете, - это то, что я хочу отговорить. –

ответ

0

Как было предложено MattDMo, я добавил следующую обработку исключений и решить эту проблему:

try: 
    AbuseEmail = results['objects'][r]['contact']['email'][0]['value'] 
    AbusePhone = results['objects'][r]['contact']['phone'][0]['value'] 
    AbuseAddress = results['objects'][r]['contact']['address'][0]['value'] 
except (KeyError, TypeError): 
    AbuseEmail = 'NULL' 
    AbusePhone = 'NULL' 
    AbuseAddress = 'NULL' 
Смежные вопросы