mcp-scraper 0.32.0 → 0.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/bin/api-server.cjs +47 -28
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +1 -1
- package/dist/bin/mcp-scraper-cli.cjs +1 -1
- package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
- package/dist/bin/mcp-scraper-cli.js +1 -1
- package/dist/bin/mcp-scraper-install.cjs +1 -1
- package/dist/bin/mcp-scraper-install.cjs.map +1 -1
- package/dist/bin/mcp-scraper-install.js +1 -1
- package/dist/bin/mcp-stdio-server.cjs +1 -1
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +2 -2
- package/dist/{chunk-YOOEAXWP.js → chunk-2FY4VBAY.js} +2 -2
- package/dist/chunk-VJBS6RPB.js +7 -0
- package/dist/chunk-VJBS6RPB.js.map +1 -0
- package/dist/{server-OBOTNFD6.js → server-GXTYKIAX.js} +49 -30
- package/dist/{server-OBOTNFD6.js.map → server-GXTYKIAX.js.map} +1 -1
- package/package.json +1 -1
- package/dist/chunk-CPQF3PYW.js +0 -7
- package/dist/chunk-CPQF3PYW.js.map +0 -1
- /package/dist/{chunk-YOOEAXWP.js.map → chunk-2FY4VBAY.js.map} +0 -0
package/README.md
CHANGED
|
@@ -88,7 +88,7 @@ Build the branded one-click bundle:
|
|
|
88
88
|
npm run build:mcpb
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.32.
|
|
91
|
+
The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.32.1`, SHA-256 `a8b3ff927f58382f5e550cbe079a4276e448c6750858ec9712f2f945cd79ffa3`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, and API-key configuration field from the bundle manifest.
|
|
92
92
|
|
|
93
93
|
The MCPB install exposes every tool — web-intelligence plus all `browser_*` tools — through the one `mcp-scraper` server.
|
|
94
94
|
|
package/dist/bin/api-server.cjs
CHANGED
|
@@ -19378,29 +19378,38 @@ var init_MapsSearchExtractor = __esm({
|
|
|
19378
19378
|
};
|
|
19379
19379
|
const phonePattern = /(?:\+?1[\s.-]?)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}/;
|
|
19380
19380
|
const addressPattern = /\b[A-Z]{2}\s+\d{5}(?:-\d{4})?\b|\b(?:St|Street|Ave|Avenue|Rd|Road|Blvd|Boulevard|Dr|Drive|Ln|Lane|Way|Pkwy|Parkway)\b/i;
|
|
19381
|
-
const
|
|
19382
|
-
const
|
|
19383
|
-
return Boolean(
|
|
19381
|
+
const headings = Array.from(document.querySelectorAll('div[role="heading"]')).filter((heading) => {
|
|
19382
|
+
const text2 = normalize4(heading.textContent);
|
|
19383
|
+
return Boolean(text2) && !/^(?:businesses|places|sponsored|people also ask|discussions and forums|more businesses|more places|custom date range|choose what you)/i.test(text2 ?? "");
|
|
19384
19384
|
});
|
|
19385
19385
|
const seen = /* @__PURE__ */ new Set();
|
|
19386
19386
|
const out = [];
|
|
19387
|
-
|
|
19388
|
-
|
|
19387
|
+
let cardIndex = -1;
|
|
19388
|
+
for (const heading of headings) {
|
|
19389
|
+
let card = heading;
|
|
19390
|
+
for (let hop = 0; hop < 8; hop++) {
|
|
19391
|
+
const parent = card.parentElement;
|
|
19392
|
+
if (!parent || parent.querySelectorAll('div[role="heading"]').length > 1) break;
|
|
19393
|
+
card = parent;
|
|
19394
|
+
}
|
|
19395
|
+
if (card.closest('[role="dialog"], dialog')) continue;
|
|
19396
|
+
const name = normalize4(heading.textContent);
|
|
19389
19397
|
if (!name) continue;
|
|
19390
|
-
const
|
|
19391
|
-
|
|
19398
|
+
const lines = (card.innerText ?? "").split("\n").map((line) => normalize4(line)).filter((line) => Boolean(line));
|
|
19399
|
+
if (/^sponsored$/i.test(lines[0] ?? "")) continue;
|
|
19400
|
+
const ratingLine = lines.find((line) => /\d(?:\.\d)?\s*\(/.test(line)) ?? "";
|
|
19401
|
+
const rating = ratingLine.match(/(\d(?:\.\d)?)\s*\(/)?.[1] ?? null;
|
|
19402
|
+
const reviewCount = ratingLine.match(/\((\d[\d,]*)\)/)?.[1]?.replace(/,/g, "") ?? null;
|
|
19403
|
+
const category = normalize4(ratingLine.split("\xB7").slice(1).join("\xB7"));
|
|
19404
|
+
const phone = lines.map((line) => line.match(phonePattern)?.[0]).find((value) => Boolean(value)) ?? null;
|
|
19405
|
+
const hoursStatus = normalize4((lines.find((line) => /\b(?:open|closed|opens|closes)\b/i.test(line)) ?? "").split("\xB7")[0] ?? "");
|
|
19406
|
+
const address = lines.find((line) => addressPattern.test(line)) ?? null;
|
|
19407
|
+
const websiteUrl = Array.from(card.querySelectorAll("a[href]")).map((anchor) => anchor.href).find((href) => /^https?:/i.test(href) && !/google\.|gstatic|googleusercontent/.test(href)) ?? null;
|
|
19408
|
+
if (!rating && !(phone && websiteUrl)) continue;
|
|
19409
|
+
const key = `${name.toLowerCase()}|${lines.join(" ").toLowerCase()}`;
|
|
19392
19410
|
if (seen.has(key)) continue;
|
|
19393
19411
|
seen.add(key);
|
|
19394
|
-
|
|
19395
|
-
const aria = normalize4(card.getAttribute("aria-label"));
|
|
19396
|
-
const rating = (aria ?? text2).match(/(?:rated\s+)?(\d(?:\.\d)?)\s*(?:out of 5)?/i)?.[1] ?? null;
|
|
19397
|
-
const reviewCount = (aria ?? text2).match(/(?:\(|·\s*)([\d,]+)\s+(?:user\s+)?reviews?\b/i)?.[1]?.replace(/,/g, "") ?? null;
|
|
19398
|
-
const phone = lines.find((line) => phonePattern.test(line)) ?? null;
|
|
19399
|
-
const address = lines.find((line) => addressPattern.test(line)) ?? null;
|
|
19400
|
-
const hoursStatus = lines.find((line) => /\b(?:open|closed|opens|closes)\b/i.test(line)) ?? null;
|
|
19401
|
-
const category = lines.find(
|
|
19402
|
-
(line) => line !== name && line !== phone && line !== address && line !== hoursStatus && !/^(?:rated|\d[\d.,]*\s*(?:out of 5|reviews?)?)\b/i.test(line) && !/sponsored|website|directions|call|save|share|more/i.test(line)
|
|
19403
|
-
) ?? null;
|
|
19412
|
+
cardIndex += 1;
|
|
19404
19413
|
const mapsSearchUrl = `https://www.google.com/maps/search/${encodeURIComponent([name, locationHint].filter(Boolean).join(" "))}`;
|
|
19405
19414
|
out.push({
|
|
19406
19415
|
cardIndex,
|
|
@@ -19415,7 +19424,7 @@ var init_MapsSearchExtractor = __esm({
|
|
|
19415
19424
|
address,
|
|
19416
19425
|
phone,
|
|
19417
19426
|
hoursStatus,
|
|
19418
|
-
websiteUrl
|
|
19427
|
+
websiteUrl,
|
|
19419
19428
|
directionsUrl: `https://www.google.com/maps/dir/?api=1&destination=${encodeURIComponent([name, address].filter(Boolean).join(", "))}`,
|
|
19420
19429
|
metadata: lines.slice(0, 20)
|
|
19421
19430
|
});
|
|
@@ -19424,17 +19433,27 @@ var init_MapsSearchExtractor = __esm({
|
|
|
19424
19433
|
}, fallbackLocation);
|
|
19425
19434
|
}
|
|
19426
19435
|
async openCardAndExtractDialog(page, card, includeServices) {
|
|
19436
|
+
if (!includeServices) return null;
|
|
19427
19437
|
const clicked = await page.evaluate((input) => {
|
|
19428
19438
|
const normalize4 = (value) => (value ?? "").replace(/\s+/g, " ").trim().toLowerCase();
|
|
19429
|
-
const
|
|
19430
|
-
|
|
19431
|
-
|
|
19432
|
-
|
|
19433
|
-
|
|
19434
|
-
|
|
19435
|
-
|
|
19436
|
-
|
|
19437
|
-
|
|
19439
|
+
const headings = Array.from(document.querySelectorAll('div[role="heading"]'));
|
|
19440
|
+
for (const heading of headings) {
|
|
19441
|
+
let target = heading;
|
|
19442
|
+
for (let hop = 0; hop < 8; hop++) {
|
|
19443
|
+
const parent = target.parentElement;
|
|
19444
|
+
if (!parent || parent.querySelectorAll('div[role="heading"]').length > 1) break;
|
|
19445
|
+
target = parent;
|
|
19446
|
+
}
|
|
19447
|
+
if (target.closest('[role="dialog"], dialog')) continue;
|
|
19448
|
+
const name = normalize4(heading.textContent);
|
|
19449
|
+
if (!name) continue;
|
|
19450
|
+
const lines = (target.innerText ?? "").split("\n").map((line) => normalize4(line)).filter(Boolean);
|
|
19451
|
+
if (`${name}|${lines.join(" ")}` !== input.cardKey) continue;
|
|
19452
|
+
target.click();
|
|
19453
|
+
return true;
|
|
19454
|
+
}
|
|
19455
|
+
return false;
|
|
19456
|
+
}, { cardKey: card.cardKey });
|
|
19438
19457
|
if (!clicked) return null;
|
|
19439
19458
|
const dialog = page.locator('dialog, [role="dialog"]').filter({ has: page.locator('h1, h2, [role="heading"]') }).last();
|
|
19440
19459
|
await dialog.waitFor({ state: "visible", timeout: 6e3 }).catch(() => {
|
|
@@ -29767,7 +29786,7 @@ var PACKAGE_VERSION;
|
|
|
29767
29786
|
var init_version = __esm({
|
|
29768
29787
|
"src/version.ts"() {
|
|
29769
29788
|
"use strict";
|
|
29770
|
-
PACKAGE_VERSION = "0.32.
|
|
29789
|
+
PACKAGE_VERSION = "0.32.1";
|
|
29771
29790
|
}
|
|
29772
29791
|
});
|
|
29773
29792
|
|