Compact Cambodia-focused Google Maps scraper powered by Camoufox
Project description
๐ฆ KhmerFox
A compact, Cambodia-focused Google Maps scraper powered by Camoufox.
Built for Khmer & English business listings. Stealth browser, async concurrency, and a modern web UI โ all in a tiny codebase.
โ ๏ธ Use responsibly. KhmerFox is intended for personal research, data you own, or publicly available listings you have permission to scrape. Always respect Google Maps Terms of Service, rate limits, and local laws. Use at your own risk.
โจ Features
| Feature | Description |
|---|---|
| ๐ Fast Async Scraping | Concurrent place extraction with configurable workers |
| ๐ฆ Stealth Browser | Camoufox anti-detect Firefox reduces blocking |
| ๐ฐ๐ญ Cambodia Defaults | Khmer query defaults, phone normalization, name splitting |
| ๐ Web UI | Modern Flask dashboard with live logs, progress, dark mode, and downloads |
| ๐ 40 Output Fields | Core + extended fields with selectable export columns |
| ๐ Multiple Formats | CSV (Excel-safe), JSON, Markdown, Excel (.xlsx) |
| ๐ Dark Mode | Toggle between light and dark themes in the web UI |
| ๐ Stop Button | Gracefully stop a running scrape from the UI |
| ๐ Cross-Platform | Windows, macOS, and Linux |
๐ฆ Installation
Requirements
- Python 3.11+
- uv package manager
- ~2 GB free disk space for Camoufox browser binaries
Install uv:
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Setup
git clone <repository-url>
cd khmerfox
uv sync
python -m camoufox fetch
python -m camoufox fetch downloads the Camoufox browser binaries for your platform. Run it again after switching OS or after updating camoufox.
๐ฅ๏ธ Web UI
The easiest way to use KhmerFox:
uv run khmerfox-web
What you get
- Settings panel โ query, format, max results, concurrency, proxy, field selection
- Output field checkboxes โ choose exactly which columns to export
- Live progress โ places found, scraped, and elapsed time
- Live logs โ color-coded, copyable, clearable
- Stop button โ stop a running scrape gracefully
- Results table โ download CSV, JSON, Markdown, or Excel with one click
- Dark / light mode โ persists in your browser
๐ป Command Line
# Default query: coffee shops in Phnom Penh (Khmer)
uv run khmerfox
# English query, all formats, 8 concurrent workers
uv run khmerfox -q "Tube Coffee in Phnom Penh" --format all --concurrency 8
# Excel only, max 50 places
uv run khmerfox -q "hotels in Siem Reap" --format xlsx --max-results 50
# Headed browser with screenshots for debugging
uv run khmerfox -q "banks in Phnom Penh" --no-headless --screenshots
# Export only selected fields
uv run khmerfox -q "coffee in Phnom Penh" --fields "name,rating,reviews,address,phone,domain"
CLI Options
| Option | Description | Default |
|---|---|---|
-q, --query |
Search query | แ แถแแแถแ แแแแแ
แแแแแแแ |
-t, --territory |
Territory for phone normalization | Cambodia |
--headless / --no-headless |
Run browser headless | headless |
--max-results |
Limit results (0 = unlimited) |
0 |
--concurrency |
Concurrent pages (1โ8) |
4 |
--format |
csv, json, md, xlsx, comma-separated, or all |
csv |
--fields |
Comma-separated output fields, or all |
core set |
--log-level |
DEBUG, INFO, WARNING, ERROR |
INFO |
--proxy |
HTTP/SOCKS5 proxy, e.g. http://127.0.0.1:8080 |
โ |
--screenshots |
Save debug screenshots on errors | โ |
--session |
Session name for Camoufox state | default |
--scroll-delay |
Seconds between scrolls in result list | 0.5 |
--page-delay |
Seconds to wait after opening a place | 0.5 |
--retries |
Retries per failed place | 1 |
๐ Output Fields
Core Fields (default)
place_id, name, name_kh, name_en, rating, reviews, category, address, phone, website, hours, price_level, plus_code, latitude, longitude, maps_url
Extended Fields
query, created_at, fulladdr, local_name, local_fulladdr, addr1, addr2, addr3, addr4, district, phone_number, international_phone_number, phone_numbers, primary_category, categories, features, url, domain, listing_url, thumbnail, reviews_url, claimed, fid, cid, timezone
Field reliability note:
name_kh/local_nameare only populated when the business name contains Khmer script.claimedonly reportsNowhen Google shows a "Claim this business" link,Yeswhen owner indicators are visible, and stays empty when the status cannot be determined.timezoneis not exposed by Google Maps and will always be empty.
๐๏ธ Project Structure
khmerfox/
โโโ khmerfox/
โ โโโ __init__.py
โ โโโ core.py # models, scraper, extractor, exporter, utils
โ โโโ cli.py # command-line interface
โ โโโ web.py # Flask app + embedded UI
โโโ data/ # output files (gitignored except .gitkeep)
โโโ sessions/ # saved browser sessions (gitignored except .gitkeep)
โโโ screenshots/ # debug screenshots (gitignored except .gitkeep)
โโโ .env.example # example environment variables
โโโ pyproject.toml # project config
โโโ uv.lock # locked dependencies
โโโ LICENSE # MIT
โโโ README.md
๐ macOS Notes
-
Install
uvusing the command above. -
Camoufox downloads the correct browser binary automatically when you run
python -m camoufox fetch. -
If macOS Gatekeeper blocks the browser, remove quarantine attributes:
xattr -rd com.apple.quarantine ~/.cache/uv/
-
Use
uv run khmerfoxanduv run khmerfox-webexactly as on other platforms.
๐ Safe Usage & Rate Limits
- Keep
--concurrencylow (2โ4) to avoid aggressive requests. - Use
--proxyto rotate IP addresses if you run repeated scrapes. - Run with
--no-headless --screenshotsfirst to visually verify behavior. - Do not scrape private or copyrighted data you are not authorized to access.
- Google Maps may block or CAPTCHA your IP if abused. KhmerFox provides no guarantee of uninterrupted access.
๐ง Environment Variables
Copy .env.example to .env and adjust:
cp .env.example .env
Supported variables: QUERY, TERRITORY, HEADLESS, FORMAT, MAX_RESULTS, CONCURRENCY, PROXY, SCREENSHOTS.
CLI flags override environment variables.
๐งโ๐ป Development
# Install dev dependencies
uv sync --dev
# Lint
uv run ruff check khmerfox/
๐ License
MIT โ see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file khmerfox-2.0.0.tar.gz.
File metadata
- Download URL: khmerfox-2.0.0.tar.gz
- Upload date:
- Size: 30.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d7704263a4824dcbac9feadef519f978169d0ac8036a74988e81bb78d1054e99
|
|
| MD5 |
fde6a85f692c4d98be09d2b8422f13cd
|
|
| BLAKE2b-256 |
9d16ffc2cff72b2040142c459190433037b62f1d5ba95dfb58098dde81ac9b13
|
Provenance
The following attestation bundles were made for khmerfox-2.0.0.tar.gz:
Publisher:
publish.yml on im4tta/khmerfox
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
khmerfox-2.0.0.tar.gz -
Subject digest:
d7704263a4824dcbac9feadef519f978169d0ac8036a74988e81bb78d1054e99 - Sigstore transparency entry: 2006808315
- Sigstore integration time:
-
Permalink:
im4tta/khmerfox@778e322d297e41ec24a678e011bfdd0a9002cb08 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/im4tta
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@778e322d297e41ec24a678e011bfdd0a9002cb08 -
Trigger Event:
release
-
Statement type:
File details
Details for the file khmerfox-2.0.0-py3-none-any.whl.
File metadata
- Download URL: khmerfox-2.0.0-py3-none-any.whl
- Upload date:
- Size: 28.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b2d0c20e5d0439cc5ff716723646c5dafc98577cfcd260990b744900153ec2b
|
|
| MD5 |
040318a8af246d321d8bc9a285937af6
|
|
| BLAKE2b-256 |
af443798f4f25cabbd4a93107b26f5acceeb4649ee4e1a47f77359b113963c8e
|
Provenance
The following attestation bundles were made for khmerfox-2.0.0-py3-none-any.whl:
Publisher:
publish.yml on im4tta/khmerfox
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
khmerfox-2.0.0-py3-none-any.whl -
Subject digest:
4b2d0c20e5d0439cc5ff716723646c5dafc98577cfcd260990b744900153ec2b - Sigstore transparency entry: 2006808474
- Sigstore integration time:
-
Permalink:
im4tta/khmerfox@778e322d297e41ec24a678e011bfdd0a9002cb08 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/im4tta
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@778e322d297e41ec24a678e011bfdd0a9002cb08 -
Trigger Event:
release
-
Statement type: