This project is a specialized automation tool designed to harvest geolocation data for speed cameras, red-light cameras, and traffic enforcement points directly from the Waze Android application. By simulating a high-speed route and scraping the device's UI layer, the script identifies alerts in real-time and logs coordinates to a structured CSV file.
The script is optimized for passive harvesting. By using a mock location application (like Lockito or Mock Locations) to simulate driving at 150 km/h, the script triggers Waze's proximity alerts. The automation then captures the exact GPS coordinates of the device at the moment the alert appears on the screen.
At this speed (approximately 41 meters per second), the script uses a 350-meter detection threshold. This provides an 8-second window to perform the UI dump and capture the location before the "vehicle" passes the radar, ensuring high efficiency without missing data points.
This function communicates with the Android system via ADB (Android Debug Bridge).
- Executes:
adb shell dumpsys location
- Uses Regular Expressions (Regex) to parse the
fusedlocation provider data. - Extracts and returns the latitude and longitude as a formatted string.
The script utilizes the uiautomator tool to generate a compressed XML dump of the current screen.
Searches the XML for text patterns like:
camera in [X] m
If a camera is detected within 350 meters, the capture sequence is triggered.
If a generic camera icon or text appears without a distance, the script logs it as a "Zero Point" capture to ensure no radar is ignored.
Every detection is saved to captured_cameras.csv with the following columns:
Latitude, Longitude, Distance, Type (Alert Text), Time
After a successful capture, the script enters a 15-second cooldown (time.sleep). This prevents the script from logging the same radar multiple times while the vehicle remains inside the alert radius.
- ADB (Android Debug Bridge) installed and configured in system environment variables.
- Python 3.x installed on your host machine.
- Android Device or Emulator with Developer Options and USB Debugging enabled.
- Mock Location App to simulate the route through the city.
Save the following file as:
extractor.py
import os
import time
import subprocess
import re
# --- CONFIGURATION ---
CSV_OUTPUT = "captured_cameras.csv"
def get_gps():
# We use raw string r'' to avoid the SyntaxWarning from brackets
cmd = r"adb shell dumpsys location | grep -m 1 'last location=Location\[fused'"
try:
line = subprocess.check_output(cmd, shell=True).decode()
# Search for pattern: fused 19.123,-99.123
m = re.search(r'fused\s+([0-9.-]+),([0-9.-]+)', line)
if m:
return f"{m.group(1)},{m.group(2)}"
except:
pass
return None
print("STARTING UNIVERSAL HARVEST (150KM/H MODE)")
print("Searching for: Speed, Red Light and Traffic Cameras...")
if not os.path.exists(CSV_OUTPUT):
with open(CSV_OUTPUT, "w") as f:
f.write("latitude,longitude,distance,type,time\n")
while True:
# 1. Interface dump (uiautomator is slow, so we increase the threshold)
os.system("adb shell 'uiautomator dump --compressed /sdcard/v.xml > /dev/null && cat /sdcard/v.xml' > view.xml")
if os.path.exists("view.xml"):
with open("view.xml", "r", encoding="utf-8") as f:
xml_data = f.read().lower()
# 2. Search for any variant of "camera" with meters
match_dist = re.search(r'text="([^"]*camera[^"]* in (\d+) m)"', xml_data)
if match_dist:
full_text = match_dist.group(1)
dist = int(match_dist.group(2))
print(f" Alert detected: {full_text}... ", end="\r")
# ADJUSTED THRESHOLD: At 150km/h (41m/s), 350m gives about 8 seconds margin
if dist <= 350:
pos = get_gps()
if pos:
print(f"\n CAPTURED! [{full_text}] at {pos}")
with open(CSV_OUTPUT, "a") as f_csv:
f_csv.write(f"{pos},{dist},{full_text},{time.strftime('%H:%M:%S')}\n")
# Sleep 15 sec to avoid capturing the same camera while passing
time.sleep(15)
# 3. Zero point or alert without meters
elif 'camera' in xml_data:
pos = get_gps()
if pos:
print(f"\n CAPTURED (ZERO POINT) -> {pos}")
with open(CSV_OUTPUT, "a") as f_csv:
f_csv.write(f"{pos},0,generic_camera,{time.strftime('%H:%M:%S')}\n")
time.sleep(15)
# Reduce loop delay slightly to make it more reactive
time.sleep(0.1)Ensure Android Debug Bridge is installed and your device is connected via USB with USB Debugging enabled.
Make sure Python 3.x is installed.
Open Waze on the device and input a route.
Use a mock location app such as:
- Lockito
- Mock Locations
Simulate the route at:
150 km/h
Run the script from your terminal:
python extractor.pyAll captured data will be stored in:
captured_cameras.csv
Example output:
latitude,longitude,distance,type,time
29.4326,-29.1332,300,speed camera in 300 m,14:32:10
29.4329,-29.1240,0,generic_camera,14:33:05
This project is for educational purposes and data research only.
Users are responsible for ensuring compliance with:
- The Terms of Service of any third-party applications.
- Local traffic laws and regulations in their jurisdiction.