"'NoneType' object is not subscriptable" OR "KeyError:" with openpyxl and ipwhois

"'NoneType' object is not subscriptable" OR "KeyError:" with openpyxl and ipwhois

我正在编写一个 python3 脚本来执行以下操作:

  1. 在工作目录中打开一个 excel 文件
  2. Select excel 文件中的第一个 sheet
  3. Select 第三列中的所有数据(在本例中为 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' 值,但随后我在 RIPE 名称上遇到 KeyError 异常。我被困住了,需要你的帮助。这是我的代码的副本:

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 = 'abuse@amazonaws.com'
      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')

根据 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'