mcp-scraper 0.2.6 → 0.2.8
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 +13 -6
- package/dist/bin/api-server.cjs +582 -171
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +2 -2
- package/dist/bin/browser-agent-stdio-server.cjs +442 -9
- package/dist/bin/browser-agent-stdio-server.cjs.map +1 -1
- package/dist/bin/browser-agent-stdio-server.js +2 -2
- package/dist/bin/mcp-scraper-combined-stdio-server.cjs +519 -31
- package/dist/bin/mcp-scraper-combined-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-scraper-combined-stdio-server.js +3 -3
- package/dist/bin/mcp-scraper-install.cjs +2 -1
- package/dist/bin/mcp-scraper-install.cjs.map +1 -1
- package/dist/bin/mcp-scraper-install.js +2 -1
- package/dist/bin/mcp-scraper-install.js.map +1 -1
- package/dist/bin/mcp-stdio-server.cjs +68 -13
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +2 -2
- package/dist/bin/paa-harvest.cjs +42 -6
- package/dist/bin/paa-harvest.cjs.map +1 -1
- package/dist/bin/paa-harvest.js +1 -1
- package/dist/chunk-5HMOPP76.js +793 -0
- package/dist/chunk-5HMOPP76.js.map +1 -0
- package/dist/{chunk-7WB2W6FO.js → chunk-6NEXSNSA.js} +69 -14
- package/dist/chunk-6NEXSNSA.js.map +1 -0
- package/dist/{chunk-MY3S7EX7.js → chunk-CQTAKXBN.js} +43 -7
- package/dist/chunk-CQTAKXBN.js.map +1 -0
- package/dist/chunk-I26QN7WQ.js +7 -0
- package/dist/chunk-I26QN7WQ.js.map +1 -0
- package/dist/index.cjs +42 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{server-MKCU3M7Y.js → server-BTTDFPSQ.js} +456 -142
- package/dist/server-BTTDFPSQ.js.map +1 -0
- package/dist/{worker-NAKGTIF5.js → worker-5O44YBF4.js} +2 -2
- package/docs/mcp-tool-quality-spec.md +3 -1
- package/package.json +1 -1
- package/dist/chunk-7WB2W6FO.js.map +0 -1
- package/dist/chunk-MY3S7EX7.js.map +0 -1
- package/dist/chunk-T6SIPPOQ.js +0 -7
- package/dist/chunk-T6SIPPOQ.js.map +0 -1
- package/dist/chunk-XL4V7VKD.js +0 -360
- package/dist/chunk-XL4V7VKD.js.map +0 -1
- package/dist/server-MKCU3M7Y.js.map +0 -1
- /package/dist/{worker-NAKGTIF5.js.map → worker-5O44YBF4.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -272,6 +272,8 @@ var MOBILE_USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X)
|
|
|
272
272
|
var DEFAULT_KERNEL_BROWSER_TIMEOUT_SECONDS = 180;
|
|
273
273
|
var KERNEL_BROWSER_CLOSE_TIMEOUT_MS = 3e3;
|
|
274
274
|
var KERNEL_SESSION_DELETE_TIMEOUT_MS = 5e3;
|
|
275
|
+
var DEFAULT_SERP_CHALLENGE_SOLVE_WAIT_MS = 2500;
|
|
276
|
+
var SERP_CHALLENGE_SOLVE_POLL_MS = 500;
|
|
275
277
|
function positiveIntFromEnv(name, fallback) {
|
|
276
278
|
const raw = process.env[name];
|
|
277
279
|
if (!raw) return fallback;
|
|
@@ -583,20 +585,20 @@ var BrowserDriver = class {
|
|
|
583
585
|
const diag = await this.captureDiagnostics(url);
|
|
584
586
|
throw new ExtractionError(`page.goto failed: ${err.message} | ${diag}`);
|
|
585
587
|
}
|
|
586
|
-
|
|
587
|
-
if (captchaCount > 0) {
|
|
588
|
+
if (await this.isSerpChallengeVisible()) {
|
|
588
589
|
await this.updateSerpNavigationDebug(navDebug, url, { hasPaa: false, captchaDetected: true });
|
|
589
|
-
|
|
590
|
+
const solved = await this.waitForSerpChallengeToClear(navDebug, url);
|
|
591
|
+
if (!solved) throw new CaptchaError(this.captchaMessage());
|
|
590
592
|
}
|
|
591
593
|
const fastFound = await this.page.waitForSelector(PAASelectors.item, { timeout: 4e3 }).catch(() => null);
|
|
592
594
|
if (fastFound) {
|
|
593
595
|
await this.updateSerpNavigationDebug(navDebug, url, { hasPaa: true, captchaDetected: false });
|
|
594
596
|
return { hasPaa: true };
|
|
595
597
|
}
|
|
596
|
-
|
|
597
|
-
if (captchaAfter > 0) {
|
|
598
|
+
if (await this.isSerpChallengeVisible()) {
|
|
598
599
|
await this.updateSerpNavigationDebug(navDebug, url, { hasPaa: false, captchaDetected: true });
|
|
599
|
-
|
|
600
|
+
const solved = await this.waitForSerpChallengeToClear(navDebug, url);
|
|
601
|
+
if (!solved) throw new CaptchaError(this.captchaMessage());
|
|
600
602
|
}
|
|
601
603
|
for (let i = 1; i <= 6; i++) {
|
|
602
604
|
await this.page.evaluate((f) => {
|
|
@@ -612,6 +614,35 @@ var BrowserDriver = class {
|
|
|
612
614
|
await this.updateSerpNavigationDebug(navDebug, url, { hasPaa: false, captchaDetected: false });
|
|
613
615
|
return { hasPaa: false };
|
|
614
616
|
}
|
|
617
|
+
async isSerpChallengeVisible() {
|
|
618
|
+
if (!this.page) return false;
|
|
619
|
+
const captchaCount = await this.page.locator(PAASelectors.captchaMarker).count().catch(() => 0);
|
|
620
|
+
if (captchaCount > 0) return true;
|
|
621
|
+
const finalUrl = this.page.url();
|
|
622
|
+
if (/google\.[^/]+\/sorry\//i.test(finalUrl)) return true;
|
|
623
|
+
const bodySnippet = await this.page.evaluate(() => {
|
|
624
|
+
const text = (document.body?.innerText ?? "").replace(/\s+/g, " ").trim();
|
|
625
|
+
return text.slice(0, 1e3);
|
|
626
|
+
}).catch(() => "");
|
|
627
|
+
return /recaptcha|unusual traffic|are you a robot|about this page|detected unusual traffic/i.test(bodySnippet);
|
|
628
|
+
}
|
|
629
|
+
async waitForSerpChallengeToClear(navDebug, requestedUrl) {
|
|
630
|
+
if (!this.kernelClient || !this.page) return false;
|
|
631
|
+
const waitMs = positiveIntFromEnv("SERP_CHALLENGE_SOLVE_WAIT_MS", DEFAULT_SERP_CHALLENGE_SOLVE_WAIT_MS);
|
|
632
|
+
const deadline = Date.now() + waitMs;
|
|
633
|
+
while (Date.now() < deadline) {
|
|
634
|
+
await this.page.waitForTimeout(Math.min(SERP_CHALLENGE_SOLVE_POLL_MS, Math.max(250, deadline - Date.now())));
|
|
635
|
+
if (!await this.isSerpChallengeVisible()) {
|
|
636
|
+
await this.page.waitForTimeout(1e3);
|
|
637
|
+
if (!await this.isSerpChallengeVisible()) {
|
|
638
|
+
await this.updateSerpNavigationDebug(navDebug, requestedUrl, { hasPaa: null, captchaDetected: false });
|
|
639
|
+
return true;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
await this.updateSerpNavigationDebug(navDebug, requestedUrl, { hasPaa: false, captchaDetected: true });
|
|
644
|
+
return false;
|
|
645
|
+
}
|
|
615
646
|
async updateSerpNavigationDebug(navDebug, requestedUrl, state) {
|
|
616
647
|
if (!navDebug || !this.page) return;
|
|
617
648
|
try {
|
|
@@ -659,7 +690,12 @@ var BrowserDriver = class {
|
|
|
659
690
|
async navigateTo(url) {
|
|
660
691
|
try {
|
|
661
692
|
await this.page.goto(url, { waitUntil: "domcontentloaded", timeout: 45e3 });
|
|
693
|
+
if (/google\.[^/]+\/search\?/i.test(url) && await this.isSerpChallengeVisible()) {
|
|
694
|
+
const solved = await this.waitForSerpChallengeToClear(null, url);
|
|
695
|
+
if (!solved) throw new CaptchaError(this.captchaMessage());
|
|
696
|
+
}
|
|
662
697
|
} catch (err) {
|
|
698
|
+
if (err instanceof CaptchaError) throw err;
|
|
663
699
|
const diag = await this.captureDiagnostics(url);
|
|
664
700
|
throw new ExtractionError(`page.goto failed: ${err.message} | ${diag}`);
|
|
665
701
|
}
|