DIY 802.11 Survey: Querying the Global WiFi Landscape with a Homemade OUI Target Deck, Python, and…
This article will explore how to use Python and the WiGLE API to analyze Wi-Fi networks in your chosen geographic area. We will focus on…
DIY 802.11 Survey: Querying the Global WiFi Landscape with a Homemade OUI Watchlist, Python, and the WiGLE API

The War-Driven World made possible by the WiGLE community of Practitioners
This article will explore how to use Python and the WiGLE API to analyze Wi-Fi networks in your chosen geographic area. We will focus on specific Wi-Fi networks of interest, filtering them based on their Organizationally Unique Identifier (OUI) and visualizing their locations on a map using Folium. This can be particularly useful for various purposes, such as network analysis, wardriving, or simply getting a better understanding of Wi-Fi distribution in a specific area.
Prerequisites
Before diving into the code, make sure you have the following:
- A WiGLE account and API key — Sign up for a free account at WiGLE and obtain an API key.
- Familiarity with Python and Jupyter Notebook.
- The following Python libraries installed:
requests,pandas, andfolium.
Import required libraries
First, we need to import the necessary libraries for this project. These include requests, pandas, folium, and others. We will also import our WiGLE API credentials from a separate file.
[embed]
Get the coordinates of your chosen geographic search area
We will use the WiGLE API to obtain the coordinates of Coney Island, New York, by passing the address to the geocode endpoint.
[embed]
{'success': True, 'results': [{'address':
{'neighbourhood': 'Coney Island', 'suburb': 'Kings County', 'city': 'City of New York', 'state': 'New York', 'postcode': '11224', 'country': 'United States', 'country_code': 'us'},
'lat': 40.57580705, 'lon': -73.9921752747697, 'importance': 0.8096053510126591, 'place_id': 253274961, 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0.
https://osm.org/copyright', 'osm_type': 'way', 'display_name': 'Coney Island, Kings County, City of New York, New York, 11224, United States',
'boundingbox': [40.571417, 40.5830258, -74.0066615, -73.980794]}]}
Get Wi-Fi network data for your geographic search area
Next, we will use the WiGLE API to obtain Wi-Fi network data within the boundaries of Coney Island. We’ll use the previously obtained coordinates to create a bounding box for our search.
[embed]
{'success': True, 'totalResults': 26055, 'first': 1, 'last': 100, 'resultCount': 100,
'results': [{'trilat': 40.57993698, 'trilong': -73.9818573, 'ssid': 'ValeriyaNetwork', 'qos': 0, 'transid': '20220117-00000', 'firsttime': '2021-11-02T19:00:00.000Z', 'lasttime': '2022-01-17T18:00:00.000Z', 'lastupdt': '2022-01-17T18:00:00.000Z',
'netid': '00:00:85:F5:B4:B1', 'name': None, 'type': 'tods', 'comment': None, 'wep': '?', 'bcninterval': 0, 'freenet': '?', 'dhcp': '?', 'paynet': '?', 'userfound': False, 'channel': 8, 'encryption': 'unknown', 'country': 'US', 'region': 'NY', 'road': 'Stillwell Avenue', 'city': 'New York', 'housenumber': '2771', 'postalcode': '11224'}, {'trilat': 40.58028793, 'trilong': -73.98207092, 'ssid': 'Maxi-CGJML9C01921', 'qos': 0, 'transid': '20211123-00000', 'firsttime': '2021-11-23T14:00:00.000Z', 'lasttime': '2021-11-23T13:00:00.000Z', 'lastupdt': '2021-11-23T13:00:00.000Z',
'netid': '00:01:19:88:AA:FF', 'name': None, 'type': 'infra', 'comment': None, 'wep': '2', 'bcninterval': 0, 'freenet': '?', 'dhcp': '?', 'paynet': '?', 'userfound': False, 'channel': 149, 'encryption': 'wpa2', 'country': 'US', 'region': 'NY', 'road': 'Stillwell Avenue', 'city': 'City of New York', 'housenumber': '2757', 'postalcode': '11224'}, {'trilat': 40.5774498, 'trilong': -73.98126221, 'ssid': 'ENCORE9E0E58', 'qos': 0, 'transid': '20120831-00000', 'firsttime': '2012-08-31T18:00:00.000Z', 'lasttime': '2012-08-31T15:00:00.000Z', 'lastupdt': '2022-08-11T21:00:00.000Z',
'netid': '00:02:6F:9E:0E:58', 'name': None, 'type': 'infra', 'comment': None, 'wep': 'W', 'bcninterval': 0, 'freenet': '?', 'dhcp': '?', 'paynet': '?', 'userfound': False, 'channel': 11, 'encryption': 'wpa', 'country': 'US', 'region': 'NY', 'road': 'Stillwell Avenue', 'city': 'City of New York', 'housenumber': None, 'postalcode': '11224'}, {'trilat': 40.57541656, 'trilong': -73.98154449, 'ssid': None, 'qos': 4, 'transid': '20150919-00000', 'firsttime': '2015-09-19T09:00:00.000Z', 'lasttime': '2017-01-09T16:00:00.000Z', 'lastupdt': '2022-08-11T21:00:00.000Z',
'netid': '00:02:6F:E1:9C:18', 'name': None, 'type': 'infra', 'comment': None, 'wep': '2', 'bcninterval': 0, 'freenet': '?', 'dhcp': '?', 'paynet': '?', 'userfound': False, 'channel': 11, 'encryption': 'wpa2', 'country': 'US', 'region': 'NY', 'road': 'Surf Avenue', 'city': 'City of New York', 'housenumber': '1310', 'postalcode': '11224'}, {'trilat': 40.57684326, 'trilong': -73.98255157, 'ssid': 'Gargiulos#4', 'qos': 0, 'transid': '20160617-00000', 'firsttime': '2016-06-17T15:00:00.000Z', 'lasttime': '2016-06-17T12:00:00.000Z', 'lastupdt': '2022-08-11T20:00:00.000Z',
'netid': '00:02:6F:E7:2F:BC', 'name': None, 'type': 'infra', 'comment': None, 'wep': '?', 'bcninterval': 0, 'freenet': '?', 'dhcp': '?', 'paynet': '?', 'userfound': False, 'channel': 11, 'encryption': 'unknown', 'country': 'US', 'region': 'NY', 'road': 'Mermaid Avenue', 'city': 'City of New York', 'housenumber': None, 'postalcode': '11224'}, {'trilat': 40.57680893, 'trilong': -73.9814682, 'ssid': 'Gargiulos#3', 'qos': 2, 'transid': '20160617-00000', 'firsttime': '2016-06-17T15:00:00.000Z', 'lasttime': '2017-01-09T16:00:00.000Z', 'lastupdt': '2022-08-11T21:00:00.000Z',
'netid': '00:02:6F:E7:2F:C4', 'name': None, 'type': 'infra', 'comment': None, 'wep': '?', 'bcninterval': 0, 'freenet': '?', 'dhcp': '?', 'paynet': '?', 'userfound': False, 'channel': 4, 'encryption': 'unknown', 'country': 'US', 'region': 'NY', 'road': 'Stillwell Avenue', 'city': 'City of New York', 'housenumber': None, 'postalcode': '11224'}, {'trilat': 40.57679749, 'trilong': -73.98264313, 'ssid': 'GARGIULOS#1', 'qos': 0, 'transid': '20160617-00000', 'firsttime': '2016-06-17T15:00:00.000Z', 'lasttime': '2016-06-17T12:00:00.000Z', 'lastupdt': '2022-08-11T20:00:00.000Z',
'netid': '00:02:6F:E7:2F:C8', 'name': None, 'type': 'infra', 'comment': None, 'wep': '?', 'bcninterval': 0, 'freenet': '?', 'dhcp': '?', 'paynet': '?', 'userfound': False, 'channel': 4, 'encryption': 'unknown', 'country': 'US', 'region': 'NY', 'road': 'West 15th Street', 'city': 'City of New York', 'housenumber': '2903', 'postalcode': '11224'}, {'trilat': 40.57676697, 'trilong': -73.9848175, 'ssid': 'Mermaid-Health', 'qos': 4, 'transid': '20140702-00000', 'firsttime': '2014-07-02T10:00:00.000Z', 'lasttime': '2016-06-07T14:00:00.000Z', 'lastupdt': '2022-08-11T18:00:00.000Z',
Create a DataFrame with Wi-Fi network data
We will now create a pandas DataFrame from the Wi-Fi network data obtained in the previous step.
[embed]
lat lon ssid qos transid firsttime lasttime lastupdt netid name ... paynet userfound channel encryption country region road city housenumber postalcode
0 40.579937 -73.981857 ValeriyaNetwork 0 20220117-00000 2021-11-02T19:00:00.000Z 2022-01-17T18:00:00.000Z 2022-01-17T18:00:00.000Z 00:00:85:F5:B4:B1 None ... ? False 8 unknown US NY Stillwell Avenue New York 2771 11224
1 40.580288 -73.982071 Maxi-CGJML9C01921 0 20211123-00000 2021-11-23T14:00:00.000Z 2021-11-23T13:00:00.000Z 2021-11-23T13:00:00.000Z 00:01:19:88:AA:FF None ... ? False 149 wpa2 US NY Stillwell Avenue City of New York 2757 11224
2 40.577450 -73.981262 ENCORE9E0E58 0 20120831-00000 2012-08-31T18:00:00.000Z 2012-08-31T15:00:00.000Z 2022-08-11T21:00:00.000Z 00:02:6F:9E:0E:58 None ... ? False 11 wpa US NY Stillwell Avenue City of New York None 11224
3 40.575417 -73.981544 None 4 20150919-00000 2015-09-19T09:00:00.000Z 2017-01-09T16:00:00.000Z 2022-08-11T21:00:00.000Z 00:02:6F:E1:9C:18 None ... ? False 11 wpa2 US NY Surf Avenue City of New York 1310 11224
4 40.576843 -73.982552 Gargiulos#4 0 20160617-00000 2016-06-17T15:00:00.000Z 2016-06-17T12:00:00.000Z 2022-08-11T20:00:00.000Z 00:02:6F:E7:2F:BC
Building a homemade OUI watchlist
To focus on specific WiFi networks, we will filter the DataFrame based on a list of Organizationally Unique Identifiers (OUIs). OUIs are the first three octets (first 24 bits) of a 48-bit MAC address and can be used to identify the vendor or manufacturer of a network device. We have already defined a watchlist of OUIs in the oui_watchlist dictionary.
[embed]
Filtering WiFi networks by OUI watchlist
Here, we define a function is_mac_in_watchlist() that takes a MAC address and a watchlist dictionary as input. It checks if the MAC address starts with any of the OUIs in the watchlist. We then apply this function to the wifi_df DataFrame, filtering out the WiFi networks that match the OUIs in the watchlist.
[embed]
Adding vendor names to the filtered DataFrame
Next, we will add a new column to the filtered DataFrame, containing the vendor names associated with the OUIs in the watchlist. We define two functions here: get_vendor() and add_vendor_column(). The get_vendor() function retrieves the vendor name corresponding to the MAC address, while the add_vendor_column() function adds a new 'vendor' column to the DataFrame. We apply the add_vendor_column() function to the filtered DataFrame, populating the 'vendor' column with the appropriate vendor names.
[embed]
Fetching MAC address details
In this step, we fetch detailed information about the filtered MAC addresses using the WiGLE API. We do this by sending a request for each MAC address in the filtered DataFrame and collecting the results in a new DataFrame.
[embed]
Visualizing the WiFi networks on a map
Now that we have the WiFi network data, it’s time to visualize it on a map. We will use the folium library to create an interactive map, placing markers for each WiFi network in the filtered DataFrame.
[embed]
Conclusion
In this article, we’ve covered how to map and analyze WiFi networks in user specified area of interest, using Python, pandas, and folium libraries. We’ve also shown how to leverage the WiGLE API to gather WiFi network data, filter it based on a list of OUI prefixes, and visualize the results on an interactive map.
This approach can be easily extended to other locations or customized to suit your specific requirements. Moreover, you can further enhance this project by incorporating other data sources or visualizations to provide more insights into WiFi networks in your area of interest.
Happy hunting!

Folium map visualization rendered in Jupyter Notebook or in-browser HTML (Bonus points if you can tell me where this is)
메타데이터
- post_id
- a12786f9366e
- slug
- diy-802-11-survey-querying-the-global-wifi-landscape-with-a-homemade-oui-target-deck-python-and-a12786f9366e
- url
- https://medium.com/@js910/diy-802-11-survey-querying-the-global-wifi-landscape-with-a-homemade-oui-target-deck-python-and-a12786f9366e
- canonical_url
- https://medium.com/@js910/diy-802-11-survey-querying-the-global-wifi-landscape-with-a-homemade-oui-target-deck-python-and-a12786f9366e
- author_url
- https://medium.com/@js910
- status
- ok
- fetched_at
- 2026-07-25 20:14:21