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.
Welcome to the Meraki Community!
To start contributing, simply sign in with your Cisco account. If you don't yet have a Cisco account, you can sign up.