Dlaczego Scrape Google Maps Data?
Mapy Google zawierają najbardziej wszechstronną bazę danych lokalnych firm na świecie. Z ponad 200 mln firm wymienionych, zawiera nazwy, adresy, numery telefonów, strony internetowe, oceny, opinie, godziny pracy i zdjęcia - wszystkie ustrukturyzowane i searchable.
Wyciąganie tych danych programowo umożliwia cenne aplikacje biznesowe:
- Wytwarzanie ołowiu: Tworzenie ukierunkowanych list przedsiębiorstw według przemysłu i lokalizacji
- Analiza konkurencyjna: Mapa konkurentów lokalizacje, oceny i opinie recenzji
- Badania rynku: Zrozumienie gęstości przedsiębiorstw, wzorców cen i zasięgu usług według obszarów
- Lokalny audyt SEO: Sprawdź listę Twojej firmy i porównaj z konkurentami
- Ubogacanie danych: Uzupełnienie danych CRM o świeże informacje biznesowe
Niniejszy przewodnik obejmuje podejścia techniczne do pobierania danych z Map Google za pomocą proxy. Aby uzyskać szersze strategie zeskrobywania SERP, zobacz nasze kompletne zeskrobywanie SERP z przewodnikiem proxy.
Google Places API vs Scraping
Przed zbudowaniem scrapera, rozważ, czy oficjalny API Google Places spełnia Twoje potrzeby.
| Współczynnik | Miejsca API | Drapanie |
|---|---|---|
| Koszt | 17 dolarów za 1000 wniosków (po wolnym poziomie) | Tylko szerokość pasma proxy (~ 0,10- 0,50 $na 1000 stron) |
| Pola danych | Zorganizowany JSON, 20 + pola | Wszystkie widoczne dane, w tym recenzje tekstu |
| Limity stawek | Ścisła granica czasu i dobowa | Ograniczone przez wielkość puli proxy |
| Tekst przeglądu | Do 5 najważniejszych przeglądów | Wszystkie opinie (z paginacją) |
| Wiarygodność | Oficjalne, stabilne punkty końcowe | Wymaga konserwacji parsera |
| Warunki świadczenia usług | W pełni zgodne | Sprawdź ToS i lokalne przepisy |
| Skala | Drogie w skali | Efektywna w dużych ilościach |
API Miejsca jest najlepszym wyborem dla małych zastosowań o krytycznym znaczeniu dla produkcji. Scraping jest bardziej opłacalne, gdy potrzebujesz dużych zbiorów danych, pełnego tekstu przeglądu lub gdy koszty API stają się zaporowe.
Struktura URL Map Google
Zrozumienie wzorców URL Map Google jest niezbędne do budowy scrapera. Istnieją dwa główne punkty wejścia:
Wyniki wyszukiwania
Wyniki wyszukiwania Map Google można uzyskać poprzez:
# Browser URL format
https://www.google.com/maps/search/restaurants+near+new+york
# URL parameters for search
https://www.google.com/maps/search/{query}/@{lat},{lng},{zoom}zSzczegóły dotyczące miejsca
Poszczególne strony biznesowe są zgodne z tym wzorem:
# Place detail URL
https://www.google.com/maps/place/{business+name}/@{lat},{lng},{zoom}z/data=!{place_id}Budowa skanera map Google
Mapy Google to aplikacja JavaScript- heavy. W przeciwieństwie do zwykłego wyszukiwania Google, proste żądania HTTP często zwracają niekompletne dane. Istnieją dwa podejścia: parkowanie wbudowanych danych JSON ze źródła strony, lub za pomocą przeglądarki bez głowy.
Podejście 1: Parsing Embedded JSON (szybciej)
Strony Map Google zawierają uporządkowane dane osadzone w źródle HTML. Oto jak go wydobyć:
import requests
import json
import re
import time
import random
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
def search_google_maps(query, location="us"):
"""Search Google Maps and extract business listings."""
proxies = {"http": PROXY_URL, "https": PROXY_URL}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9",
"Accept": "text/html,application/xhtml+xml",
}
# Use the search URL format
search_url = f"https://www.google.com/maps/search/{query.replace(' ', '+')}"
response = requests.get(
search_url,
headers=headers,
proxies=proxies,
timeout=20,
)
response.raise_for_status()
# Extract embedded JSON data from the page
# Google Maps embeds data in a specific pattern
businesses = []
# Look for business data patterns in the response
# The data is typically in a JavaScript variable
patterns = re.findall(r'\["([^"]+)",null,null,null,null,null,null,null,"([^"]*)"', response.text)
# Alternative: parse the structured search results
# Google Maps returns data in protobuf-like JSON arrays
json_matches = re.findall(r'null,\["([^"]{5,80})"[^]]*?"([^"]*?(?:St|Ave|Rd|Blvd|Dr|Ln)[^"]*?)"', response.text)
for match in json_matches[:20]:
businesses.append({
"name": match[0],
"address": match[1] if len(match) > 1 else "",
})
return businesses
results = search_google_maps("restaurants near Times Square New York")
for b in results:
print(f"{b['name']} - {b['address']}")Podejście 2: Przeglądarka bez głowy (bardziej niezawodna)
Aby uzyskać większą niezawodność ekstrakcji, użyj przeglądarki bez głowy, która czyni JavaScript:
from playwright.sync_api import sync_playwright
import json
import time
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
def scrape_maps_with_browser(query):
"""Use Playwright to scrape Google Maps with full JS rendering."""
with sync_playwright() as p:
browser = p.chromium.launch(
headless=True,
proxy={
"server": "http://gate.proxyhat.com:8080",
"username": "USERNAME",
"password": "PASSWORD",
},
)
page = browser.new_page()
page.set_extra_http_headers({
"Accept-Language": "en-US,en;q=0.9",
})
# Navigate to Google Maps search
search_url = f"https://www.google.com/maps/search/{query.replace(' ', '+')}"
page.goto(search_url, wait_until="networkidle", timeout=30000)
# Wait for results to load
page.wait_for_selector('div[role="feed"]', timeout=10000)
# Scroll to load more results
feed = page.query_selector('div[role="feed"]')
for _ in range(5):
feed.evaluate("el => el.scrollBy(0, 1000)")
time.sleep(1.5)
# Extract business data from the results
businesses = []
items = page.query_selector_all('div[role="feed"] > div > div > a')
for item in items:
name = item.get_attribute("aria-label")
href = item.get_attribute("href")
if name and href:
businesses.append({
"name": name,
"url": href,
})
browser.close()
return businesses
results = scrape_maps_with_browser("coffee shops in San Francisco")
for b in results:
print(f"{b['name']}")
print(f" {b['url'][:80]}...")
print()Wyciąganie szczegółów biznesowych
Po sporządzeniu listy adresów URL firmy, należy pobrać szczegółowe informacje z każdej listy:
import requests
import re
import json
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
def extract_business_details(maps_url):
"""Extract detailed business info from a Google Maps place page."""
proxies = {"http": PROXY_URL, "https": PROXY_URL}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9",
}
response = requests.get(maps_url, headers=headers, proxies=proxies, timeout=20)
text = response.text
business = {}
# Extract business name
name_match = re.search(r'Proxy Strategy dla Map Google
Google Maps posiada własną ochronę przed robotami, która wymaga dostosowanej strategii proxy.
Dlaczego wymagane są profile mieszkalne
Mapy Google są szczególnie agresywne w kwestii blokowania IP danych. Aplikacja ładuje dane poprzez wiele połączeń API, a Google odsyła do IP we wszystkich tych żądaniach. Proxy mieszkalne ProxyHat są niezbędne, ponieważ:
- Mijają sprawdzanie reputacji IP, że Maps API nazywa egzekwowanie
- Wspierają one wyszukiwanie na poziomie lokalnym w celu określenia lokalizacji
- Utrzymują spójne zachowanie sesji, które Maps oczekuje
Zarządzanie sesją
W przeciwieństwie do zwykłego skanowania SERP, gdzie można obracać IP na życzenie, Google Maps działa lepiej z lepkimi sesjami:
# For Google Maps, use sticky sessions (same IP for a business detail page)
# ProxyHat supports session-based rotation via the proxy URL
# See docs.proxyhat.com for session configuration
# Rotating IP (for search listings)
ROTATING_PROXY = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
# Sticky session (for individual place pages)
# Same session ID = same IP for the session duration
STICKY_PROXY = "http://USERNAME-session-maps123:PASSWORD@gate.proxyhat.com:8080"Ograniczenie stawki
Mapy Google są bardziej wrażliwe na szybkie żądania niż zwykłe wyszukiwanie Google. Należy przestrzegać niniejszych wytycznych:
- Odczekać 5- 10 sekund między wyszukiwaniem stron wyników
- Odczekać 3- 5 sekund pomiędzy pojedynczymi obciążeniami strony
- Ograniczenie równoległych próśb o uniknięcie pęknięć
- Użyj dłuższych opóźnień do przeglądu strony (8- 15 sekund między stronami)
Wdrażanie Node.js
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
const agent = new HttpsProxyAgent('http://USERNAME:PASSWORD@gate.proxyhat.com:8080');
async function searchGoogleMaps(query) {
const searchUrl = `https://www.google.com/maps/search/${encodeURIComponent(query)}`;
const { data } = await axios.get(searchUrl, {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept-Language': 'en-US,en;q=0.9',
},
httpsAgent: agent,
timeout: 20000,
});
// Extract business names from the response
const businesses = [];
const namePattern = /\["([^"]{3,80})",null,null,null,null,null,null,null/g;
let match;
while ((match = namePattern.exec(data)) !== null) {
businesses.push({ name: match[1] });
}
return businesses;
}
async function main() {
const results = await searchGoogleMaps('plumbers in Chicago');
console.log(`Found ${results.length} businesses:`);
results.forEach((b, i) => console.log(`${i + 1}. ${b.name}`));
}
main().catch(console.error);Wyciąganie opinii w skali
Przeglądy map Google należą do najcenniejszych punktów danych. Każda recenzja zawiera nazwę recenzenta, ocenę, tekst, datę, a czasami zdjęcia.
import requests
import re
import json
import time
import random
PROXY_URL = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
def extract_reviews(place_id, num_reviews=50):
"""Extract reviews for a Google Maps place using the internal API."""
proxies = {"http": PROXY_URL, "https": PROXY_URL}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9",
}
reviews = []
# Google Maps loads reviews via AJAX with pagination tokens
# The first page is loaded with the place page
maps_url = f"https://www.google.com/maps/place/?q=place_id:{place_id}"
response = requests.get(maps_url, headers=headers, proxies=proxies, timeout=20)
# Extract review data from embedded JSON
# Reviews are typically in arrays with rating, text, and author
review_pattern = re.findall(
r'"(\d)","([^"]{10,500})"[^]]*?"([^"]{2,50})"',
response.text
)
for match in review_pattern[:num_reviews]:
reviews.append({
"rating": int(match[0]),
"text": match[1],
"author": match[2],
})
return reviews
# Example: extract reviews
reviews = extract_reviews("ChIJN1t_tDeuEmsRUsoyG83frY4") # Example place ID
for r in reviews[:5]:
print(f"{'*' * r['rating']} by {r['author']}")
print(f" {r['text'][:100]}...")
print()Struktura i przechowywanie danych
Zorganizuj zeskrobywanie danych Google Maps w uporządkowany format do analizy:
import json
import csv
from datetime import datetime
def save_businesses(businesses, output_format="json"):
"""Save scraped business data in structured format."""
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
if output_format == "json":
filename = f"maps_data_{timestamp}.json"
with open(filename, "w") as f:
json.dump(businesses, f, indent=2, ensure_ascii=False)
elif output_format == "csv":
filename = f"maps_data_{timestamp}.csv"
if businesses:
keys = businesses[0].keys()
with open(filename, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=keys)
writer.writeheader()
writer.writerows(businesses)
print(f"Saved {len(businesses)} businesses to {filename}")
return filenameRozważania prawne i etyczne
Rozdrabnianie danych Google Maps rodzi ważne kwestie prawne i etyczne:
- Warunki korzystania z Google: Google 's ToS zabrania automatycznego skrobania. Rozważ użycie oficjalnego API Miejsca dla zastosowań produkcyjnych
- Ochrona danych: Dane biznesowe, takie jak numery telefonów i adresy, mogą podlegać przepisom dotyczącym ochrony danych w niektórych jurysdykcjach
- Ograniczenie stawki: Nawet z proxy, należy szanować infrastrukturę Google. Nadmierne skrobanie wpływa na jakość usług
- świeżość danych: Zawsze znacznik czasu Twoje dane i odświeżyć go regularnie, jak informacje biznesowe często się zmienia
W przypadku zastosowań o znaczeniu krytycznym należy rozważyć połączenie oficjalnego API Miejsca dla danych podstawowych z ukierunkowanym skrobaniem dla dodatkowych pól, takich jak tekst przeglądu. To podejście hybrydowe równoważy zgodność z kompletnością danych.
Więcej na temat skrobania stron internetowych najlepszych praktyk, zobacz nasz Kompletny przewodnik po proxy do skrobania stron internetowych, i dowiedzieć się o unikaniu bloków w naszym Przewodnik przeciwblokujący. Skonsultuj się z Dokumentacja ProxyHat dla szczegółów konfiguracji proxy.






