Trying to Get List of Users Connected to an AP

Jamieinbox
Getting noticed

Trying to Get List of Users Connected to an AP

I have tried and tried.

What could work- is if I could get a scrape of this page and all of the columns you can toggle on:
Network-wide->Clients

One of the columns is "Connected To."

I have been able to get decent data with this code below (also posted at Merakicode/ClientScrape at main · jadexing/Merakicode (github.com))

I also was able to pull a really nice client scrape (also on GitHub)- but none of that data shows which AP a client is connected. The goal is to choose a network, then an AP, and see the active connected clients.

HELP! (& thank you).

#This is an attempt at scraping the Meraki page Network-wide--> Clients
#This does not capture all columns, yet. This is WIP - but is solid, "As-Is."
# https://jamiegprice.substack.com/

import requests
import pandas as pd
from datetime import datetime
import time

def get_api_key():
return input("Please enter your Meraki API key: ")

def get_organizations(api_key):
url = "https://api.meraki.com/api/v1/organizations"
headers = {"X-Cisco-Meraki-API-Key": api_key}

response = requests.get(url, headers=headers)
response.raise_for_status()

return response.json()

def get_networks(api_key, org_id):
url = f"https://api.meraki.com/api/v1/organizations/{org_id}/networks"
headers = {"X-Cisco-Meraki-API-Key": api_key}

response = requests.get(url, headers=headers)
response.raise_for_status()

networks = response.json()
sorted_networks = sorted(networks, key=lambda x: x['name']) # Sort networks alphabetically by name
return sorted_networks

def get_network_clients(api_key, network_id):
url = f"https://api.meraki.com/api/v1/networks/{network_id}/clients"
headers = {"X-Cisco-Meraki-API-Key": api_key}

response = requests.get(url, headers=headers)
response.raise_for_status()

return response.json()

if __name__ == "__main__":
start_time = time.time()

try:
api_key = get_api_key()
organizations = get_organizations(api_key)

print("Numbered list of organizations:")
for idx, org in enumerate(organizations, 1):
print(f"{idx}. {org['name']}")

org_choice = int(input("Please enter the number of the organization you want to choose: "))
selected_org_id = organizations[org_choice - 1]['id']

networks = get_networks(api_key, selected_org_id)

print("Numbered list of networks:")
for idx, network in enumerate(networks, 1):
print(f"{idx}. {network['name']}")

network_choice = int(input("Please enter the number of the network you want to check clients for: "))
selected_network_id = networks[network_choice - 1]['id']

print("Fetching online wireless clients...")
network_clients = get_network_clients(api_key, selected_network_id)

print("List of online wireless clients:")
all_clients_data = []
for client in network_clients:
client_data = {
'Client Name': client.get('description', 'None'),
'MAC Address': client.get('mac', 'None'),
'IP Address': client.get('ip', 'None'),
'Status': client.get('status', 'None'),
'Manufacturer': client.get('manufacturer', 'None'),
'OS': client.get('os', 'None'),
'Usage (MB)': client['usage']['sent'] + client['usage']['recv'] if 'usage' in client else 'None',
'First Seen': client.get('firstSeen', 'None'), # No need to convert to timestamp here
'Last Seen': client.get('lastSeen', 'None'),
'SSID': client.get('ssid', 'None'),
'VLAN': client.get('vlan', 'None'),
'Hostname': client.get('dhcpHostname', 'None'),
'Access Point': client.get('apMac', 'None'),
'Switch Port': client.get('switchport', 'None'),
'User': client.get('user', 'None')
}
all_clients_data.append(client_data)

# Save data to a CSV file with today's date and time in the filename
now = datetime.now()
date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
csv_filename = f"online_wireless_clients_{date_time}.csv"
df = pd.DataFrame(all_clients_data).fillna("None")
df.to_csv(csv_filename, index=False)
print(f"Online wireless client data has been saved to {csv_filename}.")

end_time = time.time()
runtime_minutes = (end_time - start_time) // 60
runtime_seconds = (end_time - start_time) % 60
print(f"Runtime: {int(runtime_minutes)} minutes {int(runtime_seconds)} seconds")

except requests.exceptions.HTTPError as errh:
print("Http Error:", errh)
except requests.exceptions.ConnectionError as errc:
print("Error Connecting:", errc)
except requests.exceptions.Timeout as errt:
print("Timeout Error:", errt)
except requests.exceptions.RequestException as err:
print("Oops: Something Else", err)

2 Replies 2
Jamieinbox
Getting noticed

Here is my error (network and mac are correct in the code).
Error occurred during API call: 404 Client Error: Not Found for url: https://api.meraki.com/api/v1/networks/N_11223344556677/devices/66:77:11:bb:ee:ff/clients

I'm not sure what endpoint that is (with the mac address in it), but have you tried this one?


/devices/{serial}/clients


the serial is the serial of the AP you are interested in.

Get Device Clients - Meraki Dashboard API v1 - Cisco Meraki Developer Hub

Get notified when there are additional replies to this discussion.