Repository navigation
Releases
Releases · Lucifer-02/map_miner
0.3.5
[0.3.5] - 2026-09-23
Changed
- Loại Bỏ 100% Magic Numbers Trong
src/map_miner/scraper.py:- Chuyển toàn bộ các số điều khiển vận hành (timeouts, delays, intervals, viewports, thresholds) thành default parameter values trong signature hàm.
- Loại bỏ hoàn toàn số inline trần trong thân các hàm:
_create_browser_context,_pass_consent,_find_feed_selector,_scroll_feed,_get_place_urls,_scrape_query_spa,_process_link, vàscrape_google_maps. - Bổ sung bộ unit test và kiểm tra AST tự động đảm bảo không còn magic numbers trần và các tham số mới có thể override linh hoạt.
Fixed
-
Triệt Tiêu Hoàn Toàn
TimeoutNegativeWarning& Chuẩn Hóa An Toàn Timeouts:- Bọc an toàn
remaining_time = max(0.0, query_timeout - elapsed)tại tất cả các điểm kiểm tra timeout trong_get_place_urlsvà_scrape_query_spa, ngăn chặn hoàn toàn giá trị âm khi thời gian chạy vượt quá deadline. - Chuẩn hóa công thức tính
cur_timeout_mstrong SPA mode: bảo đảm luôn đạt giá trị nguyên dương$\ge 1$ (max(1, min(preview_timeout_ms, max(1000, int(max(0.0, remaining_time - 0.5) * 1000))))), loại bỏ rủi ro truyền số âm hoặc 0 vàosearch_page.expect_response. - Chuẩn hóa toàn bộ tham số timeout truyền vào Playwright APIs (
wait_for_selector,goto,get_attribute,scroll_into_view_if_needed,expect_response,click), đảm bảo luôn là số nguyên dương$\ge 1$ quamax(1, int(timeout)). - Chuẩn hóa
safe_timeout = max(1.0, float(timeout))trong_handle_captcha_if_presentđể bảo vệ coroutine giải reCAPTCHA luôn có thời gian chờ hợp lệ$\ge 1.0$ giây. - Tự động cấu hình
NODE_OPTIONS="--no-warnings"trước khi khởi tạoasync_playwrighttrongscrape_google_maps, triệt tiêu triệt để các cảnh báo nội bộ từ Node.js Playwright driver.
- Bọc an toàn
0.3.3
[0.3.3] - 2026-09-20
Added
- Cơ Chế Cứu Vãn Dữ Liệu Hai Tầng (Two-tier Zero Data Loss Rescue):
- Bổ sung tham số
results_collector: list[dict[str, Any]] | Nonetrongscrape_query_spavàlinks_collector: set[str] | Nonetrongget_place_urls. - Khởi tạo collector và truyền vào hàm cào trong
run_spa_queryvàrun_get_urls. Khi chạm Hard Watchdog Timeout (310s) hoặc gặp exception, scraper trả về toàn bộ dữ liệu đã tích lũy trong collector thay vì trả về rỗng ([]/set()), cứu vãn 100% số địa điểm đã cào được (trung bình 19.6 địa điểm/lần timeout).
- Bổ sung tham số
- Dừng Sớm Khi Liên Tiếp Ra Ngoài Bán Kính (
MAX_CONSECUTIVE_OUT_OF_RANGE_SCROLLS = 3):- Thêm hằng số
MAX_CONSECUTIVE_OUT_OF_RANGE_SCROLLS = 3. Nếu 3 lượt cuộn liên tiếp toàn bộ địa điểm mới đều vượt quárange_limit, scraper kích hoạt dừng cuộn sớm ngay lập tức, tiết kiệm tài nguyên khi cào các query mật độ thấp (nhưcourthouse).
- Thêm hằng số
- Hậu Kiểm Bán Kính Sau Bóc Tách (Post-Extraction Radius Filtering):
- Đối với các thẻ địa điểm không chứa tọa độ trên URL, sau khi bóc tách
place_datatừ preview blob, hệ thống kiểm tra khoảng cách từlatitude/longitudetrích xuất được. Nếu vượt quárange_limit, địa điểm bị loại bỏ (early drop) và không ghi nhận vào kết quả.
- Đối với các thẻ địa điểm không chứa tọa độ trên URL, sau khi bóc tách
- Bộ Tiện Ích Giải Phóng An Toàn (Graceful Shutdown & Safe Closure):
- Bổ sung các hàm
safe_close_page,safe_close_context, vàsafe_close_browserhóa giải triệt để bẫyasyncio.shield()khi task bị huỷ (cancellation). - Quản lý vòng đời task trong
global_route_handlerqua_active_route_tasks, unroute sạch sẽ trước khi đóng context, triệt tiêu hoàn toàn 479 lỗiTask was destroyed but it is pending!.
- Bổ sung các hàm
- Tái Cấu Trúc Constants thành Dataclass
ScraperConfig:- Định nghĩa dataclass
ScraperConfigtập trung hóa toàn bộ các thông số timeouts, guardrails, bộ nhớ đệm, retries và concurrency delays. - Tích hợp tham số
config: ScraperConfig | None = Nonevàoscrape_google_maps,scrape_query_spa,get_place_urlsvới cơ chế phân giải độ ưu tiên (precedence) linh hoạt. - Duy trì 100% tương thích ngược với các hằng số
DEFAULT_*vàMAX_*module-level từDEFAULT_CONFIG = ScraperConfig(). - Export
ScraperConfigvàDEFAULT_CONFIGtạimap_minervàmap_miner.scraper.
- Định nghĩa dataclass
- Bóc Tách Xử Lý Dữ Liệu Thuần Túy Ra Khỏi I/O (
src/map_miner/extractor.py):- Chuyển toàn bộ các logic xử lý dữ liệu thuần túy (pure data processing) từ
scraper.pysangextractor.py:DEFAULT_FLATTEN_COLUMNS,REQUIRED_COLUMNS,make_place_url,extract_coordinates_from_url,is_preview_response_for_link,_get_flatten_column_type,format_places_dataframe. - Bổ sung 2 hàm tiện ích tính khoảng cách và kiểm tra phạm vi:
calculate_distancevàis_within_rangehỗ trợ cảPointlẫntuple[float, float]. - Re-export toàn bộ hằng số và hàm tại
src/map_miner/scraper.pyvàsrc/map_miner/__init__.py, bảo đảm 100% tương thích ngược (Backward Compatibility). - Thay thế toàn bộ các phép tính
geodesic(...).meterstrongscraper.pybằngcalculate_distance(...).
- Chuyển toàn bộ các logic xử lý dữ liệu thuần túy (pure data processing) từ
Changed
- Tối Ưu Hóa Dừng Cuộn Trống:
- Giảm
MAX_CONSECUTIVE_EMPTY_SCROLLStừ 6 xuống 4 lượt cuộn.
- Giảm
- Kiểm Tra Deadline Chủ Động & Dynamic Preview Timeout:
- Trong
scrape_query_spa, tính toánremaining_timevà kiểm tra deadline (remaining_time <= 2.0s) ngay trong vòng lặp duyệt thẻ địa điểm và trước khi cuộn feed. - Tự động điều chỉnh động thời gian chờ preview XHR
cur_timeout_mskhông vượt quá thời gian còn lại của query.
- Trong
0.3.2
[0.3.2] - 2026-09-19
Fixed
- Vòng Lặp Cuộn Vô Hạn Khi Cạn POI Hợp Lệ (Runaway Scrolling):
- Sửa lỗi logic đếm
consecutive_empty_scrollstrongscrape_query_spa: bộ đếm giờ đây dựa trênnot found_new_in_batchthay vì bị ràng buộc bởihas_unprocessed. - Scraper chủ động ngắt cuộn feed sau
MAX_CONSECUTIVE_EMPTY_SCROLLS(6 lần) liên tiếp không có thêm POI hợp lệ trong bán kính, chấm dứt hoàn toàn tình trạng bị treo 300 giây (5 phút) ở các query phổ biến (cafe,restaurant,store, v.v.) tại khu vực thưa dân.
- Sửa lỗi logic đếm
- Playwright Strict Mode Violation Trong
scroll_feed:- Thêm
.firstvàopage.locator(feed_selector).first.hover()trongscroll_feedtrước khi gọi wheel scroll, triệt tiêu 103 lỗi strict mode khi selector fallback'div[role="main"] div[tabindex="-1"]'khớp nhiều phần tử DOM.
- Thêm
- Lỗi Driver & Pending Tasks Khi Ngắt Bằng Ctrl+C /
CancelledError:- Bọc an toàn
await asyncio.shield(resource.close())vớiexcept BaseExceptiontại tất cả các điểm giải phóng tài nguyên (context.close(),browser.close(),page.close()). - Quản lý hủy tác vụ con đồng bộ trong
scrape_google_maps, loại bỏ hoàn toàn các lỗi runtimeBrowser.close: Connection closed while reading from the drivervàTask was destroyed but it is pending!.
- Bọc an toàn
- Lỗi Báo Log ERROR Sai Lệch Khi Trang 0 Kết Quả:
- Bổ sung hàm
is_no_results_pagekiểm tra các dấu hiệu trang rỗng ("Google Maps can't find", "No results found", "Không tìm thấy kết quả",div.Q27duf). - Ghi log
INFOthông báo không tìm thấy kết quả và trả về danh sách rỗng thay vì bắnlogger.error("Could not find results feed selector on search page.").
- Bổ sung hàm
Changed
- Tối Ưu Hóa SPA Preview Timeout:
- Giảm
DEFAULT_SPA_PREVIEW_TIMEOUTtừ 15,000ms (15s) xuống 10,000ms (10s), tiết kiệm thời gian chờ lãng phí khi gặp thẻ không kích hoạt được request preview XHR trong khi vẫn đảm bảo độ trễ an toàn cho các proxy mạng chậm.
- Giảm
- Hạ Mức Độ Log Early Drop:
- Chuyển toàn bộ các vị trí ghi log
Early drop: Place ... is ...m awaytừINFOxuốngDEBUG, triệt tiêu tình trạng ngập lụt log (hơn 117,000 dòng log gây phình file 41.7MB trong log cũ).
- Chuyển toàn bộ các vị trí ghi log
- Cập Nhật Tài Liệu & Docstring Thuật Toán Xếp Hạng Google Maps:
- Bổ sung tài liệu chính thức từ Google Business Profile Help #7091 vào docstring của
range_limittạiscrape_google_maps,scrape_query_spa,get_place_urlsvà tài liệu kiến trúcCONTEXT.md. - Làm rõ 3 yếu tố xếp hạng: Relevance, Distance, Prominence và rationale của việc áp dụng cơ chế Early Drop từng phần tử kết hợp bộ đếm cuộn rỗng an toàn.
- Bổ sung tài liệu chính thức từ Google Business Profile Help #7091 vào docstring của
- Tinh Gọn Bộ Kiểm Thử (
tests/test_scraper.py):- Cắt giảm 508 dòng code boilerplate (-18.6%), từ 2,731 dòng xuống 2,222 dòng.
- Chuẩn hóa các mock helpers dùng chung (
MockPlaywrightContext,make_fake_browser,make_mock_page,make_mock_context). - Tham số hóa 7 nhóm test trùng lặp qua
@pytest.mark.parametrize, duy trì 100% độ bao phủ kiểm thử (119/119 tests pass).
Added
- Export hàm
is_no_results_pagetại tầng gốc package. - Các hằng số
NO_RESULTS_SELECTORSvàNO_RESULTS_TEXT_PATTERNS.
0.3.1
[0.3.1] - 2026-09-14
Added
- Tối Ưu Hóa Băng Thông Proxy & Cache Ứng Dụng (Application-Level Route Cache & Bypass Expansion):
- Application-Level Route Cache: Triển khai bộ nhớ đệm tầng ứng dụng
DEFAULT_STATIC_CACHE_DIR(.cache/static_assets) trongglobal_route_handlercho các static scripts và stylesheets (/maps/_/js/,/maps/_/ss/,/maps/res/, vàgstatic.comstatic assets). Phục vụ phản hồi tức thì với headerx-cache: HIT-ROUTE-CACHEkhi cache hit, loại bỏ hoàn toàn request tải lại qua proxy. - Mở Rộng Proxy Bypass: Mở rộng
DEFAULT_PROXY_BYPASSbổ sung các Google static CDN domains (fonts.gstatic.com,apis.google.com,ssl.gstatic.com), định tuyến trực tiếp static assets không tiêu tốn lưu lượng proxy dân cư. - Mở Rộng Bộ Lọc URL Rác: Bổ sung
"feedback-pa.clients6.google.com","ogads-pa.clients6.google.com","/maps/preview/entity"vàoBLOCKED_URL_PATTERNS, triệt tiêu hoàn toàn các request telemetry, quảng cáo và entity dư thừa.
- Application-Level Route Cache: Triển khai bộ nhớ đệm tầng ứng dụng
- Upper Bound Guardrails:
- Thiết lập hằng số
DEFAULT_RANGE_LIMIT = 10000.0(10 km ceiling radius) làm giới hạn bán kính tìm kiếm mặc định, bảo vệ hệ thống không cào lan man ra ngoài phạm vi địa lý dự kiến. - Đồng bộ hằng số
DEFAULT_QUERY_TIMEOUT = 300.0(5 phút) áp dụng trực tiếp xuyên suốtscrape_google_maps,scrape_query_spa, vàget_place_urls.
- Thiết lập hằng số
Changed
- Chuẩn Hóa Tham Số & Hạn Chế Kiểu
None:- Bắt buộc tham số
geo_coordinates: Pointtrongcreate_browser_contextnhằm thiết lập geolocation nhất quán, loại bỏ kiểuPoint | None = None. - Chuyển đổi các tham số sang giá trị mặc định cụ thể (Upper Bound defaults) thay vì
None:range_limit: float = DEFAULT_RANGE_LIMIT(thay vìfloat | None = None).query_timeout: float = DEFAULT_QUERY_TIMEOUT(thay vìfloat | None = None).stagger_delay: tuple[float, float] | float = (1.5, 3.5)vàcache_dir: Path | str | None = DEFAULT_CACHE_DIR.- Trong
proxy.py:password: str = ""(thay vìstr | None = None) chorenew_tor_circuit_controlvàasync_renew_tor_circuit_control;bypass: str = DEFAULT_PROXY_BYPASS(thay vìstr | None) choget_tor_rotating_proxy.
- Đơn giản hóa các khối kiểm tra điều kiện, loại bỏ việc rà soát
if range_limit is not None:hayif bypass is not None:.
- Bắt buộc tham số
- Hoàn Thiện Bộ Kiểm Thử:
- Khôi phục bộ kiểm thử dynamic versioning
tests/test_version.py(3 unit tests). - Bổ sung 6 unit tests chuyên biệt cho proxy bypass mở rộng và application-level route cache.
- Tối ưu hóa mock trong
test_staggered_query_dispatch_spađể loại bỏ hoàn toànRuntimeWarning: coroutine was never awaited. - Toàn bộ test suite đạt 100% tests pass (106 tests).
- Khôi phục bộ kiểm thử dynamic versioning
- Đóng Gói Phân Phối (Distribution Packaging):
- Đồng bộ phiên bản
0.3.1làm Single Source of Truth tạisrc/map_miner/__init__.py. - Hoàn tất đóng gói package phân phối chuẩn qua Hatchling: Wheel (
dist/map_miner-0.3.1-py3-none-any.whl) và Sdist (dist/map_miner-0.3.1.tar.gz).
- Đồng bộ phiên bản
0.3.0
[0.3.0] - 2026-09-14
Added
-
Anti-Bot & Stealth Fingerprinting:
- Chrome 131 User-Agent with a complete set of Client Hints (
sec-ch-ua,sec-ch-ua-platform,sec-ch-ua-mobile). - Emulated WebGL vendor/renderer (NVIDIA GeForce RTX 3060), eliminating headless SwiftShader/llvmpipe fingerprints.
- Emulated real-browser environment properties: plugins (
Chrome PDF Viewer), languages (en-US,en),hardwareConcurrency=8, anddeviceMemory=8.
- Chrome 131 User-Agent with a complete set of Client Hints (
-
Staggered Query Dispatch:
- Added the
stagger_delayparameter toscrape_google_maps()to introduce a randomized initial delay between queries, reducing congestion and bot detection when multiple tabs send requests simultaneously from the same IP.
- Added the
-
Tor Circuit Renewal Synchronization:
- Added a dedicated
proxy.pymodule with cooldown and lock mechanisms (DEFAULT_TOR_RENEW_COOLDOWN = 15.0s,_tor_renew_lock) to preventSIGNAL NEWNYMconflicts between concurrent threads.
- Added a dedicated
-
Offline Speech-to-Text (STT) Support:
- Integrated
voskas an offline fallback when Google STT encounters network issues or rate limits. - Added a dual-stage audio fallback: 300Hz–3400Hz band-pass filtering followed by automatic fallback to standard mono 16kHz WAV.
- Integrated
-
Configurable SPA Preview Timeout:
- Added the
preview_timeoutparameter andDEFAULT_SPA_PREVIEW_TIMEOUT = 15000(15 seconds), eliminatingTimeout 5000ms exceeded while waiting for event "response"errors when using high-latency proxies.
- Added the
Changed
- Increased CAPTCHA Solving Timeout: Increased the reCAPTCHA solving timeout from 35.0s to 85.0s (
DEFAULT_CAPTCHA_TIMEOUT = 85.0s) to better handle multi-round audio challenges. - Code Quality & Linting Standards: Enforced strict quality checks with zero technical debt:
uv run ruff check .,uv run ruff format .,ty check, and 90/90 unit tests passing.
Fixed
- Fixed missing locations in the SPA feed caused by the overly short 5000ms timeout.
- Fixed cross-tab connection interruptions when one tab triggers a Tor circuit renewal.
- Fixed Polars schema inference issues by using
infer_schema_length=None.
0.2.1
Release Notes
✨ New Features
- Real Proxy Rotation & Context Isolation: Added
ProxyRotatorandcreate_browser_context(src/map_miner/scraper.py) for per-task network isolation and zero context leaks. - Persistent Disk Cache: Added
--disk-cache-dirwith a 1 GB cap, reducing wire data transfer by ~94.5%. - Proxy Bypass: Added
DEFAULT_PROXY_BYPASSfor static assets to cut proxy bandwidth usage by ~40%. - Extended Telemetry Blocking: Aborted
client_204,cspreport, and/maps/photometabeacon requests. - Test Suite: Expanded test coverage from 27 to 41 unit tests.
🔄 Changes
- Assigned proxies at
BrowserContextlevel instead of process level. - Updated
proxytype annotations and added.cache/to.gitignore.
🐛 Bug Fixes
- Resolved HTTP/2 multiplexing issues that prevented rotating proxy gateways from rotating IPs.
- Fixed cross-query cookie and cache fingerprinting across concurrent searches.