You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python调用Shodan API获取country_code报KeyError的解决方法

Fixing KeyError: 'country_code' in Shodan Python Scripts

Hey there! That KeyError pops up because not every device result from Shodan includes full geolocation data. Some hosts might not have a location field at all, or the country_code might be missing even if location exists. Let's fix this with safe field access so your script doesn't crash unexpectedly.

Why the Error Happens

Shodan's API doesn't guarantee that every result will have a location object—for example, internal network devices, hosts with incomplete metadata, or anonymized endpoints won't provide geolocation details. Trying to directly access result['location']['country_code'] without checking if those fields exist will throw a KeyError.

Correct Implementation

Use Python's dictionary get() method to safely retrieve nested fields. This lets you set a default value (like 'N/A') if the field doesn't exist. Here's a complete working example:

import shodan

# Replace with your actual Shodan API key
SHODAN_API_KEY = 'your_api_key_here'
api = shodan.Shodan(SHODAN_API_KEY)

try:
    # Replace with your target search string
    search_query = 'your_specific_search_string_here'
    results = api.search(search_query)
    
    print(f"Total results found: {results['total']}")
    
    for result in results['matches']:
        # Safely get country code with fallback values
        country_code = result.get('location', {}).get('country_code', 'N/A')
        
        # Print key details (customize this to your needs)
        print(f"IP: {result['ip_str']} | Country Code: {country_code}")
        print(f"Sample Data: {result['data'][:60]}...\n")
        
except shodan.APIError as e:
    print(f"Shodan API Error: {e}")

How This Works

  • result.get('location', {}): If the location key doesn't exist in the result, it returns an empty dictionary instead of raising an error.
  • .get('country_code', 'N/A'): Then we check the (possibly empty) location dict for country_code. If it's missing, we return 'N/A' as a fallback.

Alternative: Conditional Checks

If you prefer explicit conditionals over chained get() calls, this works too:

for result in results['matches']:
    country_code = 'N/A'
    if 'location' in result:
        if 'country_code' in result['location']:
            country_code = result['location']['country_code']
    
    # Rest of your code...

Pro Tips

  • Filter Results Upfront: If you only want hosts with valid country codes, add country:* to your search query (e.g., 'your_query country:*'). This reduces the number of results missing geolocation data, but still keep the safe access in code for edge cases.
  • Normalize Case: Shodan returns country codes in uppercase (e.g., US, DE). Use country_code.lower() if you need lowercase values.
  • Check API Limits: Make sure you're within your Shodan API rate limits to avoid unexpected errors.

内容的提问来源于stack exchange,提问作者Store LTE

火山引擎 最新活动