domain-skill: google-maps reviews scraping#489
Conversation
…l= originals, owner-reply trap)
✅ Skill review passedReviewed 1 file(s) — no findings. |
There was a problem hiding this comment.
2 issues found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="domain-skills/google-maps/reviews.md">
<violation number="1" location="domain-skills/google-maps/reviews.md:9">
P2: The guidance overstates the reliability of the two-language `hl` heuristic. It claims that scraping in two UI languages always yields one original and one translation per review, but this only holds when a review's original language matches one of the two `hl` values. For reviews in a third language, both scrapes produce translations — so downstream consumers may mislabel translated text as "original." Consider qualifying this (e.g., "one scrape may match the reviewer's language, yielding the original, while the other is translated") or noting that the approach only works when the review language is known to match one of your chosen `hl` values. If you can access per-review language metadata (analogous to the Places API's `textLanguageCode`), that would be a more reliable signal.</violation>
<violation number="2" location="domain-skills/google-maps/reviews.md:21">
P2: The extraction example doesn't implement the deduping guard that its own documentation recommends. The 'Traps' section says duplicate `div[data-review-id]` nodes are removed by '[jsaction] filter **plus** name-presence check,' but the code block only applies the `[jsaction]` selector and never checks that `name` is truthy before processing the element. If a user copies this example, duplicate card/expanded-state nodes will be emitted as separate reviews. Consider adding a `if (!name) return;` guard (or a `data-review-id` Set) so the sample matches the described deduping logic.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
|
|
||
| - Search: `https://www.google.com/maps/search/<business>+<city>` — a unique match redirects straight to the place page. | ||
| - Direct by place_id: `https://www.google.com/maps/place/?q=place_id:<PLACE_ID>` — resolves and redirects to the canonical place URL. | ||
| - **Language matters:** Google auto-translates reviews into the UI language. Add `hl=fr` (etc.) and re-scrape to get originals — for each review, one language is the reviewer's original and the other is Google's translation. Scrape both if you need the pair. |
There was a problem hiding this comment.
P2: The guidance overstates the reliability of the two-language hl heuristic. It claims that scraping in two UI languages always yields one original and one translation per review, but this only holds when a review's original language matches one of the two hl values. For reviews in a third language, both scrapes produce translations — so downstream consumers may mislabel translated text as "original." Consider qualifying this (e.g., "one scrape may match the reviewer's language, yielding the original, while the other is translated") or noting that the approach only works when the review language is known to match one of your chosen hl values. If you can access per-review language metadata (analogous to the Places API's textLanguageCode), that would be a more reliable signal.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At domain-skills/google-maps/reviews.md, line 9:
<comment>The guidance overstates the reliability of the two-language `hl` heuristic. It claims that scraping in two UI languages always yields one original and one translation per review, but this only holds when a review's original language matches one of the two `hl` values. For reviews in a third language, both scrapes produce translations — so downstream consumers may mislabel translated text as "original." Consider qualifying this (e.g., "one scrape may match the reviewer's language, yielding the original, while the other is translated") or noting that the approach only works when the review language is known to match one of your chosen `hl` values. If you can access per-review language metadata (analogous to the Places API's `textLanguageCode`), that would be a more reliable signal.</comment>
<file context>
@@ -0,0 +1,36 @@
+
+- Search: `https://www.google.com/maps/search/<business>+<city>` — a unique match redirects straight to the place page.
+- Direct by place_id: `https://www.google.com/maps/place/?q=place_id:<PLACE_ID>` — resolves and redirects to the canonical place URL.
+- **Language matters:** Google auto-translates reviews into the UI language. Add `hl=fr` (etc.) and re-scrape to get originals — for each review, one language is the reviewer's original and the other is Google's translation. Scrape both if you need the pair.
+- The place URL contains the ftid `!1s0x...:0x<hex>` — the hex after the colon is the CID: `int(hex, 16)` → `https://maps.google.com/?cid=<decimal>`.
+- All-reviews / write-review deep links (no Maps UI): `https://search.google.com/local/reviews?placeid=<PLACE_ID>` and `https://search.google.com/local/writereview?placeid=<PLACE_ID>`.
</file context>
| - **Language matters:** Google auto-translates reviews into the UI language. Add `hl=fr` (etc.) and re-scrape to get originals — for each review, one language is the reviewer's original and the other is Google's translation. Scrape both if you need the pair. | |
| - **Language matters:** Google auto-translates reviews into the UI language. Add `hl=fr` (etc.) and re-scrape — if the reviewer's original language matches this `hl`, you'll get the original text; otherwise you'll get a Google translation. For reviews in languages other than your chosen `hl` values, both scrapes may be translations, so this heuristic only reliably yields an original/translation pair when the review language is known to match one of your `hl` settings. Scrape both if you need the pair. |
| 4. Extract per card: | ||
|
|
||
| ```js | ||
| document.querySelectorAll('div[data-review-id][jsaction]').forEach(el => { |
There was a problem hiding this comment.
P2: The extraction example doesn't implement the deduping guard that its own documentation recommends. The 'Traps' section says duplicate div[data-review-id] nodes are removed by '[jsaction] filter plus name-presence check,' but the code block only applies the [jsaction] selector and never checks that name is truthy before processing the element. If a user copies this example, duplicate card/expanded-state nodes will be emitted as separate reviews. Consider adding a if (!name) return; guard (or a data-review-id Set) so the sample matches the described deduping logic.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At domain-skills/google-maps/reviews.md, line 21:
<comment>The extraction example doesn't implement the deduping guard that its own documentation recommends. The 'Traps' section says duplicate `div[data-review-id]` nodes are removed by '[jsaction] filter **plus** name-presence check,' but the code block only applies the `[jsaction]` selector and never checks that `name` is truthy before processing the element. If a user copies this example, duplicate card/expanded-state nodes will be emitted as separate reviews. Consider adding a `if (!name) return;` guard (or a `data-review-id` Set) so the sample matches the described deduping logic.</comment>
<file context>
@@ -0,0 +1,36 @@
+4. Extract per card:
+
+```js
+document.querySelectorAll('div[data-review-id][jsaction]').forEach(el => {
+ const name = el.querySelector('.d4r55')?.textContent?.trim(); // reviewer name
+ const stars = el.querySelector('.kvMYJc')?.getAttribute('aria-label'); // "5 stars"/"5 étoiles"
</file context>
Adds domain-skills/google-maps/reviews.md — field-tested flow for scraping all reviews of a business profile: place_id / CID URL patterns, hl= language trick to get original vs auto-translated texts, feed-container scrolling, stable selectors, and the rating-only-review trap where the owner's reply leaks as the review text.
🤖 Generated with Claude Code
Summary by cubic
Add a field-tested guide for scraping all reviews from a Google Maps business profile without an API key. It shows URL patterns (search,
place_id, CID, deep links), a stable reviews-tab + feed-container scroll + expand flow, how to usehl=to capture originals vs translations, and traps like rating-only reviews leaking owner replies.Written for commit 823c3f4. Summary will update on new commits.