web-fetcher-mcp 1.0.9 → 1.0.13
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 +312 -98
- package/dist/index.js +550 -3
- package/dist/index.js.map +1 -1
- package/dist/tools/click-element.d.ts +1 -1
- package/dist/tools/click-element.d.ts.map +1 -1
- package/dist/tools/click-element.js +219 -4
- package/dist/tools/click-element.js.map +1 -1
- package/dist/tools/execute-js.d.ts +16 -0
- package/dist/tools/execute-js.d.ts.map +1 -0
- package/dist/tools/execute-js.js +79 -0
- package/dist/tools/execute-js.js.map +1 -0
- package/dist/tools/get-console-logs.d.ts +6 -0
- package/dist/tools/get-console-logs.d.ts.map +1 -0
- package/dist/tools/get-console-logs.js +85 -0
- package/dist/tools/get-console-logs.js.map +1 -0
- package/dist/tools/get-element-attributes.d.ts +10 -0
- package/dist/tools/get-element-attributes.d.ts.map +1 -0
- package/dist/tools/get-element-attributes.js +90 -0
- package/dist/tools/get-element-attributes.js.map +1 -0
- package/dist/tools/get-page-info.d.ts +14 -0
- package/dist/tools/get-page-info.d.ts.map +1 -0
- package/dist/tools/get-page-info.js +163 -0
- package/dist/tools/get-page-info.js.map +1 -0
- package/dist/tools/hover-element.d.ts +9 -0
- package/dist/tools/hover-element.d.ts.map +1 -0
- package/dist/tools/hover-element.js +90 -0
- package/dist/tools/hover-element.js.map +1 -0
- package/dist/tools/navigate-history.d.ts +8 -0
- package/dist/tools/navigate-history.d.ts.map +1 -0
- package/dist/tools/navigate-history.js +45 -0
- package/dist/tools/navigate-history.js.map +1 -0
- package/dist/tools/open-devtools.d.ts +18 -0
- package/dist/tools/open-devtools.d.ts.map +1 -0
- package/dist/tools/open-devtools.js +64 -0
- package/dist/tools/open-devtools.js.map +1 -0
- package/dist/tools/scroll-page.d.ts +11 -0
- package/dist/tools/scroll-page.d.ts.map +1 -0
- package/dist/tools/scroll-page.js +85 -0
- package/dist/tools/scroll-page.js.map +1 -0
- package/dist/tools/select-option.d.ts +12 -0
- package/dist/tools/select-option.d.ts.map +1 -0
- package/dist/tools/select-option.js +197 -0
- package/dist/tools/select-option.js.map +1 -0
- package/dist/tools/upload-file.d.ts +10 -0
- package/dist/tools/upload-file.d.ts.map +1 -0
- package/dist/tools/upload-file.js +99 -0
- package/dist/tools/upload-file.js.map +1 -0
- package/dist/tools/wait-for-element.d.ts +11 -0
- package/dist/tools/wait-for-element.d.ts.map +1 -0
- package/dist/tools/wait-for-element.js +68 -0
- package/dist/tools/wait-for-element.js.map +1 -0
- package/dist/tools/web-page-fetcher.js +1 -1
- package/dist/tools/web-page-fetcher.js.map +1 -1
- package/dist/types/index.d.ts +111 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/browser.d.ts.map +1 -1
- package/dist/utils/browser.js +12 -11
- package/dist/utils/browser.js.map +1 -1
- package/dist/utils/console-logger.d.ts +27 -0
- package/dist/utils/console-logger.d.ts.map +1 -0
- package/dist/utils/console-logger.js +274 -0
- package/dist/utils/console-logger.js.map +1 -0
- package/dist/utils/html-skeleton.d.ts +6 -0
- package/dist/utils/html-skeleton.d.ts.map +1 -0
- package/dist/utils/html-skeleton.js +63 -0
- package/dist/utils/html-skeleton.js.map +1 -0
- package/dist/utils/page-content.d.ts.map +1 -1
- package/dist/utils/page-content.js +9 -55
- package/dist/utils/page-content.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { GetElementAttributesResult } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* 获取元素的属性
|
|
4
|
+
* @param url 网页 URL,如果是 'current' 则使用当前已打开的页面
|
|
5
|
+
* @param selector CSS 选择器
|
|
6
|
+
* @param attributes 要获取的属性名列表,为空则获取所有属性
|
|
7
|
+
* @param useExistingPage 是否使用已存在的页面,默认 true
|
|
8
|
+
*/
|
|
9
|
+
export declare function getElementAttributes(url: string | undefined, selector: string, attributes?: string[], useExistingPage?: boolean): Promise<GetElementAttributesResult>;
|
|
10
|
+
//# sourceMappingURL=get-element-attributes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-element-attributes.d.ts","sourceRoot":"","sources":["../../src/tools/get-element-attributes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAEpE;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,YAAY,EACvB,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,MAAM,EAAO,EACzB,eAAe,GAAE,OAAc,GAC9B,OAAO,CAAC,0BAA0B,CAAC,CAwFrC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { getBrowser, getPage, closeBrowser } from '../utils/browser.js';
|
|
2
|
+
/**
|
|
3
|
+
* 获取元素的属性
|
|
4
|
+
* @param url 网页 URL,如果是 'current' 则使用当前已打开的页面
|
|
5
|
+
* @param selector CSS 选择器
|
|
6
|
+
* @param attributes 要获取的属性名列表,为空则获取所有属性
|
|
7
|
+
* @param useExistingPage 是否使用已存在的页面,默认 true
|
|
8
|
+
*/
|
|
9
|
+
export async function getElementAttributes(url = 'current', selector, attributes = [], useExistingPage = true) {
|
|
10
|
+
const { browser, useExistingBrowser } = await getBrowser();
|
|
11
|
+
try {
|
|
12
|
+
const page = await getPage(browser, useExistingBrowser, useExistingPage ? 'current' : url);
|
|
13
|
+
if (!useExistingPage && url !== 'current') {
|
|
14
|
+
await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
|
|
15
|
+
}
|
|
16
|
+
console.error(`获取元素属性: ${selector}`);
|
|
17
|
+
const result = await page.evaluate((sel, attrs) => {
|
|
18
|
+
const element = document.querySelector(sel);
|
|
19
|
+
if (!element)
|
|
20
|
+
return null;
|
|
21
|
+
// 获取所有属性
|
|
22
|
+
const allAttributes = {};
|
|
23
|
+
if (element.attributes) {
|
|
24
|
+
for (let i = 0; i < element.attributes.length; i++) {
|
|
25
|
+
const attr = element.attributes[i];
|
|
26
|
+
allAttributes[attr.name] = attr.value;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// 如果指定了属性列表,只返回指定的属性
|
|
30
|
+
const filteredAttributes = {};
|
|
31
|
+
if (attrs.length > 0) {
|
|
32
|
+
for (const attr of attrs) {
|
|
33
|
+
if (attr in allAttributes) {
|
|
34
|
+
filteredAttributes[attr] = allAttributes[attr];
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// 尝试从元素属性获取(如 value, checked 等 DOM 属性)
|
|
38
|
+
const domValue = element[attr];
|
|
39
|
+
if (domValue !== undefined && domValue !== null) {
|
|
40
|
+
filteredAttributes[attr] = String(domValue);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
attributes: filteredAttributes,
|
|
46
|
+
elementInfo: {
|
|
47
|
+
tagName: element.tagName.toLowerCase(),
|
|
48
|
+
id: element.id || undefined,
|
|
49
|
+
className: element.className || undefined,
|
|
50
|
+
text: element.textContent?.trim().slice(0, 200) || undefined,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
attributes: allAttributes,
|
|
56
|
+
elementInfo: {
|
|
57
|
+
tagName: element.tagName.toLowerCase(),
|
|
58
|
+
id: element.id || undefined,
|
|
59
|
+
className: element.className || undefined,
|
|
60
|
+
text: element.textContent?.trim().slice(0, 200) || undefined,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}, selector, attributes);
|
|
64
|
+
if (!result) {
|
|
65
|
+
await closeBrowser(browser, useExistingBrowser, true);
|
|
66
|
+
return {
|
|
67
|
+
success: false,
|
|
68
|
+
error: `未找到元素: ${selector}`,
|
|
69
|
+
attributes: {},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
console.error(`获取属性成功,共 ${Object.keys(result.attributes).length} 个属性`);
|
|
73
|
+
await closeBrowser(browser, useExistingBrowser, true);
|
|
74
|
+
return {
|
|
75
|
+
success: true,
|
|
76
|
+
attributes: result.attributes,
|
|
77
|
+
elementInfo: result.elementInfo,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
console.error('获取元素属性失败:', error);
|
|
82
|
+
await closeBrowser(browser, useExistingBrowser, true);
|
|
83
|
+
return {
|
|
84
|
+
success: false,
|
|
85
|
+
error: error.message || '未知错误',
|
|
86
|
+
attributes: {},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=get-element-attributes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-element-attributes.js","sourceRoot":"","sources":["../../src/tools/get-element-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAc,SAAS,EACvB,QAAgB,EAChB,aAAuB,EAAE,EACzB,kBAA2B,IAAI;IAE/B,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;IAE3D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,kBAAkB,EAAE,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAE3F,IAAI,CAAC,eAAe,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YAC1C,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,WAAW,QAAQ,EAAE,CAAC,CAAC;QAErC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAW,EAAE,KAAe,EAAE,EAAE;YAClE,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAuB,CAAC;YAClE,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC;YAE1B,SAAS;YACT,MAAM,aAAa,GAA2B,EAAE,CAAC;YACjD,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;gBACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACnD,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;oBACnC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;gBACxC,CAAC;YACH,CAAC;YAED,qBAAqB;YACrB,MAAM,kBAAkB,GAA2B,EAAE,CAAC;YACtD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,IAAI,IAAI,aAAa,EAAE,CAAC;wBAC1B,kBAAkB,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;oBACjD,CAAC;yBAAM,CAAC;wBACN,uCAAuC;wBACvC,MAAM,QAAQ,GAAI,OAAe,CAAC,IAAI,CAAC,CAAC;wBACxC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;4BAChD,kBAAkB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;wBAC9C,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,OAAO;oBACL,UAAU,EAAE,kBAAkB;oBAC9B,WAAW,EAAE;wBACX,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE;wBACtC,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,SAAS;wBAC3B,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS;wBACzC,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,SAAS;qBAC7D;iBACF,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,UAAU,EAAE,aAAa;gBACzB,WAAW,EAAE;oBACX,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE;oBACtC,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,SAAS;oBAC3B,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS;oBACzC,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,SAAS;iBAC7D;aACF,CAAC;QACJ,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAEzB,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,YAAY,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;YACtD,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,UAAU,QAAQ,EAAE;gBAC3B,UAAU,EAAE,EAAE;aACf,CAAC;QACJ,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,YAAY,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC;QAEvE,MAAM,YAAY,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;QAEtD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;SAChC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAClC,MAAM,YAAY,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;QACtD,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,MAAM;YAC9B,UAAU,EAAE,EAAE;SACf,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { GetPageInfoResult } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* 获取当前页面的信息(不刷新页面)
|
|
4
|
+
* @param url 网页 URL,如果是 'current' 则使用当前已打开的页面
|
|
5
|
+
* @param includeHtmlSkeleton 是否返回 HTML 骨架结构,默认 false
|
|
6
|
+
* @param includeFormElements 是否返回页面表单元素信息,默认 false
|
|
7
|
+
* @param includeText 是否返回页面文本内容,默认 true
|
|
8
|
+
* @param contentSelector 内容选择器,用于指定要提取内容的 HTML 元素,默认 'body'
|
|
9
|
+
* @param useExistingPage 是否使用已存在的页面,默认 true
|
|
10
|
+
* @param downloadImages 是否下载图片并转换为 base64,默认 false
|
|
11
|
+
* @returns 页面信息结果
|
|
12
|
+
*/
|
|
13
|
+
export declare function getPageInfo(url?: string, includeHtmlSkeleton?: boolean, includeFormElements?: boolean, includeText?: boolean, contentSelector?: string, useExistingPage?: boolean, downloadImages?: boolean): Promise<GetPageInfoResult>;
|
|
14
|
+
//# sourceMappingURL=get-page-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-page-info.d.ts","sourceRoot":"","sources":["../../src/tools/get-page-info.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAmB,MAAM,mBAAmB,CAAC;AAE5E;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAC/B,GAAG,GAAE,MAAkB,EACvB,mBAAmB,GAAE,OAAe,EACpC,mBAAmB,GAAE,OAAe,EACpC,WAAW,GAAE,OAAc,EAC3B,eAAe,GAAE,MAAe,EAChC,eAAe,GAAE,OAAc,EAC/B,cAAc,GAAE,OAAe,GAC9B,OAAO,CAAC,iBAAiB,CAAC,CA6K5B"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { getBrowser, getPage, closeBrowser } from '../utils/browser.js';
|
|
2
|
+
import { downloadAndConvertImage } from '../utils/images.js';
|
|
3
|
+
import { getHtmlSkeleton } from '../utils/html-skeleton.js';
|
|
4
|
+
/**
|
|
5
|
+
* 获取当前页面的信息(不刷新页面)
|
|
6
|
+
* @param url 网页 URL,如果是 'current' 则使用当前已打开的页面
|
|
7
|
+
* @param includeHtmlSkeleton 是否返回 HTML 骨架结构,默认 false
|
|
8
|
+
* @param includeFormElements 是否返回页面表单元素信息,默认 false
|
|
9
|
+
* @param includeText 是否返回页面文本内容,默认 true
|
|
10
|
+
* @param contentSelector 内容选择器,用于指定要提取内容的 HTML 元素,默认 'body'
|
|
11
|
+
* @param useExistingPage 是否使用已存在的页面,默认 true
|
|
12
|
+
* @param downloadImages 是否下载图片并转换为 base64,默认 false
|
|
13
|
+
* @returns 页面信息结果
|
|
14
|
+
*/
|
|
15
|
+
export async function getPageInfo(url = 'current', includeHtmlSkeleton = false, includeFormElements = false, includeText = true, contentSelector = 'body', useExistingPage = true, downloadImages = false) {
|
|
16
|
+
let browserConnection = null;
|
|
17
|
+
try {
|
|
18
|
+
// 获取浏览器实例
|
|
19
|
+
browserConnection = await getBrowser();
|
|
20
|
+
const { browser, useExistingBrowser } = browserConnection;
|
|
21
|
+
// 获取页面(复用当前页面,不刷新)
|
|
22
|
+
const page = await getPage(browser, useExistingBrowser, useExistingPage ? 'current' : url);
|
|
23
|
+
// 如果不是使用当前页面且指定了 URL,才需要导航
|
|
24
|
+
if (!useExistingPage && url !== 'current') {
|
|
25
|
+
console.error(`正在导航到: ${url}`);
|
|
26
|
+
await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
|
|
27
|
+
}
|
|
28
|
+
console.error('正在获取页面信息(不刷新)...');
|
|
29
|
+
// 等待页面网络空闲
|
|
30
|
+
await page.waitForNetworkIdle({ timeout: 5000 }).catch(() => {
|
|
31
|
+
// 忽略超时,继续执行
|
|
32
|
+
});
|
|
33
|
+
// 提取页面信息
|
|
34
|
+
const pageInfo = await page.evaluate((selector, includeSkeleton, includeFormElems, includeTxt, skeletonFuncStr) => {
|
|
35
|
+
// eslint-disable-next-line no-eval
|
|
36
|
+
const getHtmlSkeleton = eval(`(${skeletonFuncStr})`);
|
|
37
|
+
// 查找目标元素
|
|
38
|
+
let targetElement = document.querySelector(selector);
|
|
39
|
+
// 如果没找到指定元素,使用 body
|
|
40
|
+
if (!targetElement) {
|
|
41
|
+
targetElement = document.body;
|
|
42
|
+
}
|
|
43
|
+
let text = '';
|
|
44
|
+
let images = [];
|
|
45
|
+
// 提取文本内容
|
|
46
|
+
if (includeTxt && targetElement) {
|
|
47
|
+
text = targetElement.innerText || '';
|
|
48
|
+
}
|
|
49
|
+
// 提取图片 URL
|
|
50
|
+
if (targetElement) {
|
|
51
|
+
const imgElements = targetElement.querySelectorAll('img');
|
|
52
|
+
imgElements.forEach((img) => {
|
|
53
|
+
const src = img.getAttribute('src') || img.getAttribute('data-src');
|
|
54
|
+
if (src) {
|
|
55
|
+
images.push(src);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
// 提取表单元素
|
|
60
|
+
const formElements = [];
|
|
61
|
+
if (includeFormElems) {
|
|
62
|
+
const allInputs = document.querySelectorAll('input, button, textarea, select, [role="button"]');
|
|
63
|
+
allInputs.forEach((el, index) => {
|
|
64
|
+
const element = el;
|
|
65
|
+
const tagName = element.tagName.toLowerCase();
|
|
66
|
+
const inputType = element.getAttribute('type') || '';
|
|
67
|
+
const id = element.id || '';
|
|
68
|
+
const className = element.className || '';
|
|
69
|
+
const name = element.getAttribute('name') || '';
|
|
70
|
+
const placeholder = element.getAttribute('placeholder') || '';
|
|
71
|
+
const textContent = element.textContent?.trim() || '';
|
|
72
|
+
// 生成推荐的选择器
|
|
73
|
+
let selectorStr = '';
|
|
74
|
+
if (id) {
|
|
75
|
+
selectorStr = `#${id}`;
|
|
76
|
+
}
|
|
77
|
+
else if (name) {
|
|
78
|
+
selectorStr = `${tagName}[name="${name}"]`;
|
|
79
|
+
}
|
|
80
|
+
else if (className) {
|
|
81
|
+
const classes = className.split(' ').filter(c => c).join('.');
|
|
82
|
+
selectorStr = `.${classes}`;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
selectorStr = `${tagName}:nth-of-type(${index + 1})`;
|
|
86
|
+
}
|
|
87
|
+
// 只保留重要的表单元素
|
|
88
|
+
const isImportant = tagName === 'button' ||
|
|
89
|
+
tagName === 'input' && ['text', 'password', 'email', 'tel', 'checkbox', 'submit', 'button'].includes(inputType) ||
|
|
90
|
+
tagName === 'textarea' ||
|
|
91
|
+
tagName === 'select' ||
|
|
92
|
+
element.getAttribute('role') === 'button' ||
|
|
93
|
+
/登录|Login|提交|Submit|同意|Agree|注册|Register/i.test(textContent);
|
|
94
|
+
if (isImportant) {
|
|
95
|
+
formElements.push({
|
|
96
|
+
tagName,
|
|
97
|
+
type: inputType || undefined,
|
|
98
|
+
name: name || undefined,
|
|
99
|
+
id: id || undefined,
|
|
100
|
+
className: className || undefined,
|
|
101
|
+
placeholder: placeholder || undefined,
|
|
102
|
+
value: element.value || textContent || undefined,
|
|
103
|
+
selector: selectorStr
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
// 生成 HTML 骨架
|
|
109
|
+
const htmlSkeleton = includeSkeleton ? getHtmlSkeleton(document.body) : '';
|
|
110
|
+
// 获取页面标题和 URL
|
|
111
|
+
const title = document.title || '';
|
|
112
|
+
const pageUrl = window.location.href;
|
|
113
|
+
return {
|
|
114
|
+
title,
|
|
115
|
+
url: pageUrl,
|
|
116
|
+
text: text.slice(0, 50000),
|
|
117
|
+
images: images.slice(0, 100),
|
|
118
|
+
formElements: formElements.slice(0, 50),
|
|
119
|
+
htmlSkeleton: htmlSkeleton ? htmlSkeleton.slice(0, 100000) : undefined
|
|
120
|
+
};
|
|
121
|
+
}, contentSelector, includeHtmlSkeleton, includeFormElements, includeText, getHtmlSkeleton.toString());
|
|
122
|
+
// 下载图片(如果需要)
|
|
123
|
+
const downloadedImages = [];
|
|
124
|
+
if (downloadImages && pageInfo.images.length > 0) {
|
|
125
|
+
console.error(`找到 ${pageInfo.images.length} 张图片,开始下载...`);
|
|
126
|
+
const cookies = await page.cookies();
|
|
127
|
+
const pageUrl = page.url();
|
|
128
|
+
for (const imageUrl of pageInfo.images) {
|
|
129
|
+
const downloadedImage = await downloadAndConvertImage(imageUrl, cookies, pageUrl);
|
|
130
|
+
if (downloadedImage) {
|
|
131
|
+
downloadedImages.push(downloadedImage);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
console.error(`成功下载 ${downloadedImages.length} 张图片`);
|
|
135
|
+
}
|
|
136
|
+
console.error('页面信息获取成功');
|
|
137
|
+
// 保持浏览器打开
|
|
138
|
+
await closeBrowser(browser, useExistingBrowser, true);
|
|
139
|
+
return {
|
|
140
|
+
success: true,
|
|
141
|
+
...pageInfo,
|
|
142
|
+
downloadedImages
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
console.error('获取页面信息失败:', error);
|
|
147
|
+
if (browserConnection) {
|
|
148
|
+
const { browser, useExistingBrowser } = browserConnection;
|
|
149
|
+
await closeBrowser(browser, useExistingBrowser, true);
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
success: false,
|
|
153
|
+
error: error.message || '未知错误',
|
|
154
|
+
title: '',
|
|
155
|
+
url: '',
|
|
156
|
+
text: '',
|
|
157
|
+
images: [],
|
|
158
|
+
formElements: [],
|
|
159
|
+
htmlSkeleton: undefined
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=get-page-info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-page-info.js","sourceRoot":"","sources":["../../src/tools/get-page-info.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { HoverElementResult } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* 鼠标悬停在指定元素上
|
|
4
|
+
* @param url 网页 URL,如果是 'current' 则使用当前已打开的页面
|
|
5
|
+
* @param selector CSS 选择器
|
|
6
|
+
* @param useExistingPage 是否使用已存在的页面,默认 true
|
|
7
|
+
*/
|
|
8
|
+
export declare function hoverElement(url: string | undefined, selector: string, useExistingPage?: boolean): Promise<HoverElementResult>;
|
|
9
|
+
//# sourceMappingURL=hover-element.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hover-element.d.ts","sourceRoot":"","sources":["../../src/tools/hover-element.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,YAAY,EACvB,QAAQ,EAAE,MAAM,EAChB,eAAe,GAAE,OAAc,GAC9B,OAAO,CAAC,kBAAkB,CAAC,CA+F7B"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { getBrowser, getPage, closeBrowser } from '../utils/browser.js';
|
|
2
|
+
/**
|
|
3
|
+
* 鼠标悬停在指定元素上
|
|
4
|
+
* @param url 网页 URL,如果是 'current' 则使用当前已打开的页面
|
|
5
|
+
* @param selector CSS 选择器
|
|
6
|
+
* @param useExistingPage 是否使用已存在的页面,默认 true
|
|
7
|
+
*/
|
|
8
|
+
export async function hoverElement(url = 'current', selector, useExistingPage = true) {
|
|
9
|
+
const { browser, useExistingBrowser } = await getBrowser();
|
|
10
|
+
try {
|
|
11
|
+
const page = await getPage(browser, useExistingBrowser, useExistingPage ? 'current' : url);
|
|
12
|
+
if (!useExistingPage && url !== 'current') {
|
|
13
|
+
await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
|
|
14
|
+
}
|
|
15
|
+
console.error(`正在悬停到元素: ${selector}`);
|
|
16
|
+
// 先获取元素信息
|
|
17
|
+
const elementInfo = await page.evaluate((sel) => {
|
|
18
|
+
const element = document.querySelector(sel);
|
|
19
|
+
if (!element)
|
|
20
|
+
return null;
|
|
21
|
+
return {
|
|
22
|
+
tagName: element.tagName.toLowerCase(),
|
|
23
|
+
type: element.getAttribute('type') || undefined,
|
|
24
|
+
name: element.getAttribute('name') || undefined,
|
|
25
|
+
id: element.id || undefined,
|
|
26
|
+
className: element.className || undefined,
|
|
27
|
+
text: element.textContent?.trim().slice(0, 200) || undefined,
|
|
28
|
+
};
|
|
29
|
+
}, selector);
|
|
30
|
+
if (!elementInfo) {
|
|
31
|
+
await closeBrowser(browser, useExistingBrowser, true);
|
|
32
|
+
return {
|
|
33
|
+
success: false,
|
|
34
|
+
error: `未找到元素: ${selector}`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// 使用 Puppeteer 的 hover 方法
|
|
38
|
+
const element = await page.$(selector);
|
|
39
|
+
if (!element) {
|
|
40
|
+
await closeBrowser(browser, useExistingBrowser, true);
|
|
41
|
+
return {
|
|
42
|
+
success: false,
|
|
43
|
+
error: `未找到元素: ${selector}`,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// 滚动到元素可见
|
|
47
|
+
await element.evaluate((el) => {
|
|
48
|
+
el.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
49
|
+
});
|
|
50
|
+
// 等待滚动完成
|
|
51
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
52
|
+
// 执行 hover
|
|
53
|
+
await element.hover();
|
|
54
|
+
// 也通过 JS 触发 mouseover/mouseenter 事件(兼容性更好)
|
|
55
|
+
await page.evaluate((sel) => {
|
|
56
|
+
const element = document.querySelector(sel);
|
|
57
|
+
if (element) {
|
|
58
|
+
const mouseoverEvent = new MouseEvent('mouseover', {
|
|
59
|
+
bubbles: true,
|
|
60
|
+
cancelable: true,
|
|
61
|
+
view: window,
|
|
62
|
+
});
|
|
63
|
+
element.dispatchEvent(mouseoverEvent);
|
|
64
|
+
const mouseenterEvent = new MouseEvent('mouseenter', {
|
|
65
|
+
bubbles: true,
|
|
66
|
+
cancelable: true,
|
|
67
|
+
view: window,
|
|
68
|
+
});
|
|
69
|
+
element.dispatchEvent(mouseenterEvent);
|
|
70
|
+
}
|
|
71
|
+
}, selector);
|
|
72
|
+
console.error(`悬停成功: ${elementInfo.tagName}`);
|
|
73
|
+
// 等待可能的动画/下拉菜单
|
|
74
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
75
|
+
await closeBrowser(browser, useExistingBrowser, true);
|
|
76
|
+
return {
|
|
77
|
+
success: true,
|
|
78
|
+
elementInfo,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
console.error('悬停失败:', error);
|
|
83
|
+
await closeBrowser(browser, useExistingBrowser, true);
|
|
84
|
+
return {
|
|
85
|
+
success: false,
|
|
86
|
+
error: error.message || '未知错误',
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=hover-element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hover-element.js","sourceRoot":"","sources":["../../src/tools/hover-element.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NavigateHistoryResult } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* 导航历史:前进或后退
|
|
4
|
+
* @param direction 方向:back(后退) / forward(前进)
|
|
5
|
+
* @param steps 步数(仅对后退有效),默认 1
|
|
6
|
+
*/
|
|
7
|
+
export declare function navigateHistory(direction?: 'back' | 'forward', steps?: number): Promise<NavigateHistoryResult>;
|
|
8
|
+
//# sourceMappingURL=navigate-history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigate-history.d.ts","sourceRoot":"","sources":["../../src/tools/navigate-history.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE/D;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,SAAS,GAAE,MAAM,GAAG,SAAkB,EACtC,KAAK,GAAE,MAAU,GAChB,OAAO,CAAC,qBAAqB,CAAC,CA2ChC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { getBrowser, getPage, closeBrowser } from '../utils/browser.js';
|
|
2
|
+
/**
|
|
3
|
+
* 导航历史:前进或后退
|
|
4
|
+
* @param direction 方向:back(后退) / forward(前进)
|
|
5
|
+
* @param steps 步数(仅对后退有效),默认 1
|
|
6
|
+
*/
|
|
7
|
+
export async function navigateHistory(direction = 'back', steps = 1) {
|
|
8
|
+
const { browser, useExistingBrowser } = await getBrowser();
|
|
9
|
+
try {
|
|
10
|
+
const page = await getPage(browser, useExistingBrowser, 'current');
|
|
11
|
+
console.error(`导航历史: ${direction === 'back' ? '后退' : '前进'} ${steps} 步`);
|
|
12
|
+
if (direction === 'back') {
|
|
13
|
+
await page.goBack();
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
await page.goForward();
|
|
17
|
+
}
|
|
18
|
+
// 等待页面加载
|
|
19
|
+
await page.waitForNetworkIdle({ timeout: 10000 }).catch(() => {
|
|
20
|
+
console.error('页面加载超时,继续执行...');
|
|
21
|
+
});
|
|
22
|
+
const url = page.url();
|
|
23
|
+
const title = await page.title();
|
|
24
|
+
console.error(`导航完成: ${title} (${url})`);
|
|
25
|
+
await closeBrowser(browser, useExistingBrowser, true);
|
|
26
|
+
return {
|
|
27
|
+
success: true,
|
|
28
|
+
url,
|
|
29
|
+
title,
|
|
30
|
+
direction,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.error('导航失败:', error);
|
|
35
|
+
await closeBrowser(browser, useExistingBrowser, true);
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
error: error.message || '未知错误',
|
|
39
|
+
url: '',
|
|
40
|
+
title: '',
|
|
41
|
+
direction,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=navigate-history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigate-history.js","sourceRoot":"","sources":["../../src/tools/navigate-history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,YAAgC,MAAM,EACtC,QAAgB,CAAC;IAEjB,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;IAE3D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,kBAAkB,EAAE,SAAS,CAAC,CAAC;QAEnE,OAAO,CAAC,KAAK,CAAC,SAAS,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC;QAExE,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YACzB,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACzB,CAAC;QAED,SAAS;QACT,MAAM,IAAI,CAAC,kBAAkB,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YAC3D,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAEjC,OAAO,CAAC,KAAK,CAAC,SAAS,KAAK,KAAK,GAAG,GAAG,CAAC,CAAC;QAEzC,MAAM,YAAY,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;QAEtD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,GAAG;YACH,KAAK;YACL,SAAS;SACV,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC9B,MAAM,YAAY,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;QACtD,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,MAAM;YAC9B,GAAG,EAAE,EAAE;YACP,KAAK,EAAE,EAAE;YACT,SAAS;SACV,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 打开浏览器开发者工具
|
|
3
|
+
* @param url 网页 URL,如果是 'current' 则使用当前已打开的页面
|
|
4
|
+
* @param isMobile 是否开启手机设备模式,默认 false
|
|
5
|
+
* @param mobileDevice 模拟的手机设备型号,如:iPhone 13、Pixel 5 等
|
|
6
|
+
* @param useExistingPage 是否使用已存在的页面,默认 true
|
|
7
|
+
* @returns 操作结果
|
|
8
|
+
*/
|
|
9
|
+
export declare function openDevtools(url: string, isMobile?: boolean, mobileDevice?: string, useExistingPage?: boolean): Promise<{
|
|
10
|
+
success: boolean;
|
|
11
|
+
error?: string;
|
|
12
|
+
url: string;
|
|
13
|
+
viewport?: {
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
};
|
|
17
|
+
}>;
|
|
18
|
+
//# sourceMappingURL=open-devtools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-devtools.d.ts","sourceRoot":"","sources":["../../src/tools/open-devtools.ts"],"names":[],"mappings":"AAgBA;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,OAAe,EACzB,YAAY,GAAE,MAAoB,EAClC,eAAe,GAAE,OAAc,GAC9B,OAAO,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE;QACT,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CAAC,CA4DD"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { KnownDevices } from 'puppeteer';
|
|
2
|
+
import { getBrowser, getPage, closeBrowser } from '../utils/browser.js';
|
|
3
|
+
/**
|
|
4
|
+
* 打开浏览器开发者工具
|
|
5
|
+
* @param url 网页 URL,如果是 'current' 则使用当前已打开的页面
|
|
6
|
+
* @param isMobile 是否开启手机设备模式,默认 false
|
|
7
|
+
* @param mobileDevice 模拟的手机设备型号,如:iPhone 13、Pixel 5 等
|
|
8
|
+
* @param useExistingPage 是否使用已存在的页面,默认 true
|
|
9
|
+
* @returns 操作结果
|
|
10
|
+
*/
|
|
11
|
+
export async function openDevtools(url, isMobile = false, mobileDevice = 'iPhone 13', useExistingPage = true) {
|
|
12
|
+
const { browser, useExistingBrowser } = await getBrowser();
|
|
13
|
+
let page;
|
|
14
|
+
try {
|
|
15
|
+
page = await getPage(browser, useExistingBrowser, url);
|
|
16
|
+
// 获取当前页面 URL
|
|
17
|
+
const currentUrl = page.url();
|
|
18
|
+
console.error(`当前页面 URL: ${currentUrl}`);
|
|
19
|
+
let viewport;
|
|
20
|
+
// 如果开启手机设备模式
|
|
21
|
+
if (isMobile) {
|
|
22
|
+
console.error(`正在设置手机设备模式: ${mobileDevice}`);
|
|
23
|
+
// 获取所有设备并查找匹配的
|
|
24
|
+
const deviceEntries = Object.entries(KnownDevices);
|
|
25
|
+
const device = deviceEntries.find(([name]) => name.toLowerCase().includes(mobileDevice.toLowerCase()));
|
|
26
|
+
if (device) {
|
|
27
|
+
const [deviceName, deviceConfig] = device;
|
|
28
|
+
await page.emulate(deviceConfig);
|
|
29
|
+
viewport = { width: deviceConfig.viewport.width, height: deviceConfig.viewport.height };
|
|
30
|
+
console.error(`已模拟设备: ${deviceName}, 视口: ${viewport.width}x${viewport.height}`);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// 如果找不到预设设备,使用默认的 iPhone 13 配置
|
|
34
|
+
const defaultDevice = deviceEntries.find(([name]) => name === 'iPhone 13');
|
|
35
|
+
if (defaultDevice) {
|
|
36
|
+
const [deviceName, deviceConfig] = defaultDevice;
|
|
37
|
+
await page.emulate(deviceConfig);
|
|
38
|
+
viewport = { width: deviceConfig.viewport.width, height: deviceConfig.viewport.height };
|
|
39
|
+
console.error(`未找到设备 "${mobileDevice}",使用默认设备: iPhone 13`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// 确保页面获得焦点
|
|
44
|
+
await page.bringToFront();
|
|
45
|
+
console.error('开发者工具已激活,请在浏览器中查看');
|
|
46
|
+
return {
|
|
47
|
+
success: true,
|
|
48
|
+
url: currentUrl,
|
|
49
|
+
viewport: viewport,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error('打开开发者工具失败:', error.message);
|
|
54
|
+
return {
|
|
55
|
+
success: false,
|
|
56
|
+
error: error.message,
|
|
57
|
+
url: '',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
await closeBrowser(browser, useExistingBrowser, true);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=open-devtools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-devtools.js","sourceRoot":"","sources":["../../src/tools/open-devtools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ScrollPageResult } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* 滚动页面
|
|
4
|
+
* @param url 网页 URL,如果是 'current' 则使用当前已打开的页面
|
|
5
|
+
* @param direction 滚动方向:up/down/left/right
|
|
6
|
+
* @param amount 滚动量(像素),默认 500
|
|
7
|
+
* @param selector 可选的 CSS 选择器,如果提供则滚动到该元素位置
|
|
8
|
+
* @param useExistingPage 是否使用已存在的页面,默认 true
|
|
9
|
+
*/
|
|
10
|
+
export declare function scrollPage(url?: string, direction?: 'up' | 'down' | 'left' | 'right', amount?: number, selector?: string, useExistingPage?: boolean): Promise<ScrollPageResult>;
|
|
11
|
+
//# sourceMappingURL=scroll-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scroll-page.d.ts","sourceRoot":"","sources":["../../src/tools/scroll-page.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,GAAG,GAAE,MAAkB,EACvB,SAAS,GAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAgB,EACpD,MAAM,GAAE,MAAY,EACpB,QAAQ,CAAC,EAAE,MAAM,EACjB,eAAe,GAAE,OAAc,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAkF3B"}
|