web-fetcher-mcp 1.0.0

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.
Files changed (58) hide show
  1. package/README.md +185 -0
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +278 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/tools/click-element.d.ts +3 -0
  7. package/dist/tools/click-element.d.ts.map +1 -0
  8. package/dist/tools/click-element.js +166 -0
  9. package/dist/tools/click-element.js.map +1 -0
  10. package/dist/tools/focus-input.d.ts +3 -0
  11. package/dist/tools/focus-input.d.ts.map +1 -0
  12. package/dist/tools/focus-input.js +78 -0
  13. package/dist/tools/focus-input.js.map +1 -0
  14. package/dist/tools/tapd-bug-fetcher.d.ts +20 -0
  15. package/dist/tools/tapd-bug-fetcher.d.ts.map +1 -0
  16. package/dist/tools/tapd-bug-fetcher.js +376 -0
  17. package/dist/tools/tapd-bug-fetcher.js.map +1 -0
  18. package/dist/tools/type-input.d.ts +3 -0
  19. package/dist/tools/type-input.d.ts.map +1 -0
  20. package/dist/tools/type-input.js +97 -0
  21. package/dist/tools/type-input.js.map +1 -0
  22. package/dist/tools/utils/utils.d.ts +2 -0
  23. package/dist/tools/utils/utils.d.ts.map +1 -0
  24. package/dist/tools/utils/utils.js +7 -0
  25. package/dist/tools/utils/utils.js.map +1 -0
  26. package/dist/tools/web-page-fetcher.d.ts +3 -0
  27. package/dist/tools/web-page-fetcher.d.ts.map +1 -0
  28. package/dist/tools/web-page-fetcher.js +100 -0
  29. package/dist/tools/web-page-fetcher.js.map +1 -0
  30. package/dist/types/index.d.ts +73 -0
  31. package/dist/types/index.d.ts.map +1 -0
  32. package/dist/types/index.js +3 -0
  33. package/dist/types/index.js.map +1 -0
  34. package/dist/utils/browser.d.ts +6 -0
  35. package/dist/utils/browser.d.ts.map +1 -0
  36. package/dist/utils/browser.js +95 -0
  37. package/dist/utils/browser.js.map +1 -0
  38. package/dist/utils/config.d.ts +7 -0
  39. package/dist/utils/config.d.ts.map +1 -0
  40. package/dist/utils/config.js +11 -0
  41. package/dist/utils/config.js.map +1 -0
  42. package/dist/utils/cookies.d.ts +5 -0
  43. package/dist/utils/cookies.d.ts.map +1 -0
  44. package/dist/utils/cookies.js +46 -0
  45. package/dist/utils/cookies.js.map +1 -0
  46. package/dist/utils/images.d.ts +5 -0
  47. package/dist/utils/images.d.ts.map +1 -0
  48. package/dist/utils/images.js +59 -0
  49. package/dist/utils/images.js.map +1 -0
  50. package/dist/utils/login-check.d.ts +4 -0
  51. package/dist/utils/login-check.d.ts.map +1 -0
  52. package/dist/utils/login-check.js +110 -0
  53. package/dist/utils/login-check.js.map +1 -0
  54. package/dist/utils/page-content.d.ts +4 -0
  55. package/dist/utils/page-content.d.ts.map +1 -0
  56. package/dist/utils/page-content.js +139 -0
  57. package/dist/utils/page-content.js.map +1 -0
  58. package/package.json +47 -0
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # Web Page Fetcher MCP
2
+
3
+ 一个通用的 MCP 工具,可以获取任意网页的内容(包括文字和图片),支持需要登录的页面。
4
+
5
+ ## 功能概述
6
+
7
+ - 获取任意网页的文本内容
8
+ - 下载网页中的图片并转换为 Base64
9
+ - 支持需要登录的页面
10
+ - 自动保存和复用登录状态(Cookie)
11
+ - 可自定义内容选择器,精准提取页面特定区域
12
+
13
+ ## 使用方法
14
+
15
+ ### 工具 1: fetch-web-page
16
+
17
+ 获取网页内容(文字和图片)
18
+
19
+ ### 参数说明
20
+
21
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
22
+ |------|------|------|--------|------|
23
+ | url | string | 是 | - | 网页的完整 URL |
24
+ | contentSelector | string | 否 | 'body' | 内容选择器,用于指定要提取内容的 HTML 元素 |
25
+ | downloadImages | boolean | 否 | true | 是否下载图片 |
26
+ | loginMode | string | 否 | 'skip' | 登录模式:skip/auto/manual |
27
+ | waitForLogin | boolean | 否 | false | 检测到需要登录时是否等待用户手动登录 |
28
+
29
+ ### 登录模式说明
30
+
31
+ - **skip** (默认): 不检测登录状态,直接获取页面内容
32
+ - **auto**: 使用保存的 Cookie 自动登录
33
+ - **manual**: 打开浏览器等待用户手动完成登录
34
+
35
+ ### 示例调用
36
+
37
+ #### 普通网页抓取
38
+ ```json
39
+ {
40
+ "name": "fetch-web-page",
41
+ "arguments": {
42
+ "url": "https://cloud.tencent.com/document/product/866/43106"
43
+ }
44
+ }
45
+ ```
46
+
47
+ #### 抓取特定区域内容
48
+ ```json
49
+ {
50
+ "name": "fetch-web-page",
51
+ "arguments": {
52
+ "url": "https://example.com/article/123",
53
+ "contentSelector": ".article-content"
54
+ }
55
+ }
56
+ ```
57
+
58
+ #### 需要登录的页面(首次)
59
+ ```json
60
+ {
61
+ "name": "fetch-web-page",
62
+ "arguments": {
63
+ "url": "https://internal.example.com/dashboard",
64
+ "loginMode": "manual",
65
+ "waitForLogin": true
66
+ }
67
+ }
68
+ ```
69
+
70
+ #### 需要登录的页面(后续)
71
+ ```json
72
+ {
73
+ "name": "fetch-web-page",
74
+ "arguments": {
75
+ "url": "https://internal.example.com/dashboard",
76
+ "loginMode": "auto"
77
+ }
78
+ }
79
+ ```
80
+
81
+ ---
82
+
83
+ ### 工具 2: focus-input-element
84
+
85
+ 获取页面输入框焦点,支持通过 CSS 选择器定位元素。
86
+
87
+ #### 参数说明
88
+
89
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
90
+ |------|------|------|--------|------|
91
+ | url | string | 否 | 'current' | 网页 URL,使用 'current' 则操作当前已打开的页面 |
92
+ | selector | string | 是 | - | CSS 选择器,支持类名、ID、属性选择器等 |
93
+ | useExistingPage | boolean | 否 | true | 是否使用已存在的页面 |
94
+
95
+ #### 示例调用
96
+
97
+ ##### 通过 ID 获取焦点
98
+ ```json
99
+ {
100
+ "name": "focus-input-element",
101
+ "arguments": {
102
+ "selector": "#username"
103
+ }
104
+ }
105
+ ```
106
+
107
+ ##### 通过类名获取焦点
108
+ ```json
109
+ {
110
+ "name": "focus-input-element",
111
+ "arguments": {
112
+ "selector": ".search-input"
113
+ }
114
+ }
115
+ ```
116
+
117
+ ##### 通过属性选择器获取焦点
118
+ ```json
119
+ {
120
+ "name": "focus-input-element",
121
+ "arguments": {
122
+ "selector": "input[name='email']"
123
+ }
124
+ }
125
+ ```
126
+
127
+ ##### 操作特定页面的输入框
128
+ ```json
129
+ {
130
+ "name": "focus-input-element",
131
+ "arguments": {
132
+ "url": "https://example.com/login",
133
+ "selector": "#password"
134
+ }
135
+ }
136
+ ```
137
+
138
+ #### 返回结果
139
+
140
+ 成功时返回元素信息:
141
+ ```
142
+ ✅ 成功获取焦点!
143
+
144
+ 元素信息:
145
+ - 标签: input
146
+ - 类型: text
147
+ - ID: username
148
+ - Name: user
149
+ - Class: form-control
150
+ - Placeholder: 请输入用户名
151
+ - 当前值:
152
+ ```
153
+
154
+ ## 数据存储
155
+
156
+ - **Cookie 存储位置**: `~/.web-fetcher-mcp/cookies.json`
157
+ - **图片存储位置**: `~/.web-fetcher-mcp/images/`
158
+
159
+ ## 系统要求
160
+
161
+ - Node.js 18+
162
+ - Google Chrome 浏览器
163
+
164
+ ## 安装和运行
165
+
166
+ ```bash
167
+ # 安装依赖
168
+ npm install
169
+
170
+ # 构建
171
+ npm run build
172
+
173
+ # 运行
174
+ npm start
175
+ ```
176
+
177
+ ## 使用已有 Chrome 实例(推荐)
178
+
179
+ 如需使用日常浏览器的书签和登录状态,先用以下命令启动 Chrome:
180
+
181
+ ```bash
182
+ "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222
183
+ ```
184
+
185
+ 然后 MCP 工具会自动连接到该实例。
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,278 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
+ import { z } from 'zod';
6
+ import { fetchWebPage } from './tools/web-page-fetcher.js';
7
+ import { focusInputElement } from './tools/focus-input.js';
8
+ import { typeInputElement } from './tools/type-input.js';
9
+ import { clickElement } from './tools/click-element.js';
10
+ // 定义工具列表
11
+ const tools = [
12
+ {
13
+ name: 'fetch-web-page',
14
+ description: '获取任意网页的内容(包括文字和图片)。支持需要登录的页面,首次访问需要手动登录时会自动保存登录状态。',
15
+ inputSchema: z.object({
16
+ url: z.string().describe('网页的完整 URL,例如:https://cloud.tencent.com/document/product/866/43106'),
17
+ contentSelector: z.string().optional().default('body').describe('内容选择器,用于指定要提取内容的 HTML 元素,默认值为 "body"'),
18
+ downloadImages: z.boolean().optional().default(true).describe('是否下载图片,默认值为 true'),
19
+ loginMode: z.enum(['auto', 'manual', 'skip']).optional().default('skip').describe('登录模式:skip - 不检测登录(默认);auto - 使用保存的 Cookie 自动登录;manual - 手动登录(首次访问或 Cookie 过期时使用)'),
20
+ waitForLogin: z.boolean().optional().default(false).describe('当检测到需要登录时是否等待用户手动登录,默认值为 false'),
21
+ }),
22
+ },
23
+ {
24
+ name: 'focus-input-element',
25
+ description: '通过 CSS 选择器获取页面上的输入框焦点。支持类名、ID、标签名等任意 CSS 选择器。',
26
+ inputSchema: z.object({
27
+ url: z.string().optional().default('current').describe('网页 URL,如果是 current 则使用当前已打开的页面'),
28
+ selector: z.string().describe('CSS 选择器,例如:#username、.search-input、input[name="email"]'),
29
+ useExistingPage: z.boolean().optional().default(true).describe('是否使用已存在的页面,默认 true'),
30
+ }),
31
+ },
32
+ {
33
+ name: 'type-input-element',
34
+ description: '在指定的输入框中输入文本内容。支持先清空输入框,支持输入后按回车。',
35
+ inputSchema: z.object({
36
+ url: z.string().optional().default('current').describe('网页 URL,如果是 current 则使用当前已打开的页面'),
37
+ selector: z.string().describe('CSS 选择器,例如:#kw、.search-input、input[name="wd"]'),
38
+ text: z.string().describe('要输入的文本内容'),
39
+ clearFirst: z.boolean().optional().default(true).describe('是否先清空输入框,默认 true'),
40
+ pressEnter: z.boolean().optional().default(false).describe('输入后是否按回车键,默认 false'),
41
+ useExistingPage: z.boolean().optional().default(true).describe('是否使用已存在的页面,默认 true'),
42
+ }),
43
+ },
44
+ {
45
+ name: 'click-element',
46
+ description: '点击页面上的指定元素。支持按钮、链接、复选框等任意可点击元素。',
47
+ inputSchema: z.object({
48
+ url: z.string().optional().default('current').describe('网页 URL,如果是 current 则使用当前已打开的页面'),
49
+ selector: z.string().describe('CSS 选择器,例如:#login-btn、.submit-button、button[type="submit"]'),
50
+ useExistingPage: z.boolean().optional().default(true).describe('是否使用已存在的页面,默认 true'),
51
+ }),
52
+ },
53
+ ];
54
+ // 创建 MCP Server
55
+ const server = new Server({
56
+ name: 'web-fetcher-mcp',
57
+ version: '1.0.0',
58
+ }, {
59
+ capabilities: {
60
+ tools: {},
61
+ },
62
+ });
63
+ // 处理工具列表请求
64
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
65
+ return {
66
+ tools: tools.map((tool) => ({
67
+ name: tool.name,
68
+ description: tool.description,
69
+ inputSchema: tool.inputSchema,
70
+ })),
71
+ };
72
+ });
73
+ // 处理工具调用请求
74
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
75
+ const { name, arguments: args } = request.params;
76
+ if (name === 'fetch-web-page') {
77
+ const validatedArgs = tools[0].inputSchema.parse(args);
78
+ console.error(`正在获取网页: ${validatedArgs.url}`);
79
+ const result = await fetchWebPage(validatedArgs.url, validatedArgs.contentSelector || 'body', validatedArgs.downloadImages !== false, validatedArgs.loginMode || 'skip', validatedArgs.waitForLogin || false);
80
+ if (result.success && result.content) {
81
+ const contentParts = [];
82
+ // 添加表单元素信息(如果有)
83
+ if (result.content.formElements && result.content.formElements.length > 0) {
84
+ contentParts.push({
85
+ type: 'text',
86
+ text: `\n📋 页面表单元素 (${result.content.formElements.length} 个):\n`,
87
+ });
88
+ result.content.formElements.forEach((el, i) => {
89
+ let elInfo = `${i + 1}. <${el.tagName}`;
90
+ if (el.type)
91
+ elInfo += ` type="${el.type}"`;
92
+ if (el.id)
93
+ elInfo += ` id="${el.id}"`;
94
+ if (el.name)
95
+ elInfo += ` name="${el.name}"`;
96
+ if (el.placeholder)
97
+ elInfo += ` placeholder="${el.placeholder.slice(0, 30)}"`;
98
+ if (el.value)
99
+ elInfo += ` value="${el.value.slice(0, 30)}"`;
100
+ elInfo += `>\n 选择器: ${el.selector}\n`;
101
+ contentParts.push({
102
+ type: 'text',
103
+ text: elInfo,
104
+ });
105
+ });
106
+ }
107
+ // 添加 HTML 骨架(如果有)
108
+ if (result.content.htmlSkeleton) {
109
+ contentParts.push({
110
+ type: 'text',
111
+ text: `\n🦴 HTML 骨架:\n\`\`\`html\n${result.content.htmlSkeleton}\n\`\`\`\n`,
112
+ });
113
+ }
114
+ // 添加文本内容
115
+ if (result.content.text) {
116
+ contentParts.push({
117
+ type: 'text',
118
+ text: `\n📝 页面文本内容:\n${result.content.text}`,
119
+ });
120
+ }
121
+ // 添加下载的图片
122
+ if (result.content.downloadedImages && result.content.downloadedImages.length > 0) {
123
+ contentParts.push({
124
+ type: 'text',
125
+ text: `\n已下载 ${result.content.downloadedImages.length} 张图片:\n`,
126
+ });
127
+ for (let i = 0; i < result.content.downloadedImages.length; i++) {
128
+ const img = result.content.downloadedImages[i];
129
+ contentParts.push({
130
+ type: 'text',
131
+ text: `图片 ${i + 1}: ${img.filename}\n原始链接:${img.originalUrl}\n`,
132
+ });
133
+ contentParts.push({
134
+ type: 'image',
135
+ data: img.base64,
136
+ mimeType: 'image/png',
137
+ });
138
+ }
139
+ }
140
+ else if (result.content.images && result.content.images.length > 0) {
141
+ contentParts.push({
142
+ type: 'text',
143
+ text: `\n找到的图片链接 (${result.content.images.length} 张):\n` +
144
+ result.content.images.map((img, i) => `${i + 1}. ${img}`).join('\n'),
145
+ });
146
+ }
147
+ return { content: contentParts };
148
+ }
149
+ else {
150
+ return {
151
+ content: [{
152
+ type: 'text',
153
+ text: `获取失败:${result.error || '未知错误'}`,
154
+ }],
155
+ };
156
+ }
157
+ }
158
+ if (name === 'focus-input-element') {
159
+ const validatedArgs = tools[1].inputSchema.parse(args);
160
+ console.error(`正在获取输入框焦点: ${validatedArgs.selector}`);
161
+ const result = await focusInputElement(validatedArgs.url, validatedArgs.selector, validatedArgs.useExistingPage !== false);
162
+ if (result.success) {
163
+ const info = result.elementInfo;
164
+ let responseText = `✅ 成功获取焦点!\n\n`;
165
+ responseText += `元素信息:\n`;
166
+ responseText += `- 标签: ${info?.tagName}\n`;
167
+ if (info?.type)
168
+ responseText += `- 类型: ${info.type}\n`;
169
+ if (info?.id)
170
+ responseText += `- ID: ${info.id}\n`;
171
+ if (info?.name)
172
+ responseText += `- Name: ${info.name}\n`;
173
+ if (info?.className)
174
+ responseText += `- Class: ${info.className}\n`;
175
+ if (info?.placeholder)
176
+ responseText += `- Placeholder: ${info.placeholder}\n`;
177
+ if (info?.value)
178
+ responseText += `- 当前值: ${info.value}\n`;
179
+ return {
180
+ content: [{
181
+ type: 'text',
182
+ text: responseText,
183
+ }],
184
+ };
185
+ }
186
+ else {
187
+ return {
188
+ content: [{
189
+ type: 'text',
190
+ text: `❌ 获取焦点失败:${result.error || '未知错误'}`,
191
+ }],
192
+ };
193
+ }
194
+ }
195
+ if (name === 'type-input-element') {
196
+ const validatedArgs = tools[2].inputSchema.parse(args);
197
+ console.error(`正在输入内容到: ${validatedArgs.selector}`);
198
+ const result = await typeInputElement(validatedArgs.url, validatedArgs.selector, validatedArgs.text, validatedArgs.clearFirst !== false, validatedArgs.pressEnter || false, validatedArgs.useExistingPage !== false);
199
+ if (result.success) {
200
+ const info = result.elementInfo;
201
+ let responseText = `✅ 输入成功!\n\n`;
202
+ responseText += `输入内容: ${validatedArgs.text}\n`;
203
+ if (validatedArgs.pressEnter)
204
+ responseText += `已按回车键\n`;
205
+ responseText += `\n元素信息:\n`;
206
+ responseText += `- 标签: ${info?.tagName}\n`;
207
+ if (info?.id)
208
+ responseText += `- ID: ${info.id}\n`;
209
+ if (info?.name)
210
+ responseText += `- Name: ${info.name}\n`;
211
+ if (info?.value)
212
+ responseText += `- 当前值: ${info.value}\n`;
213
+ return {
214
+ content: [{
215
+ type: 'text',
216
+ text: responseText,
217
+ }],
218
+ };
219
+ }
220
+ else {
221
+ return {
222
+ content: [{
223
+ type: 'text',
224
+ text: `❌ 输入失败:${result.error || '未知错误'}`,
225
+ }],
226
+ };
227
+ }
228
+ }
229
+ if (name === 'click-element') {
230
+ const validatedArgs = tools[3].inputSchema.parse(args);
231
+ console.error(`正在点击元素: ${validatedArgs.selector}`);
232
+ const result = await clickElement(validatedArgs.url, validatedArgs.selector, validatedArgs.useExistingPage !== false);
233
+ if (result.success) {
234
+ const info = result.elementInfo;
235
+ let responseText = `✅ 点击成功!\n\n`;
236
+ responseText += `元素信息:\n`;
237
+ responseText += `- 标签: ${info?.tagName}\n`;
238
+ if (info?.type)
239
+ responseText += `- 类型: ${info.type}\n`;
240
+ if (info?.id)
241
+ responseText += `- ID: ${info.id}\n`;
242
+ if (info?.name)
243
+ responseText += `- Name: ${info.name}\n`;
244
+ if (info?.className)
245
+ responseText += `- Class: ${info.className}\n`;
246
+ if (info?.text)
247
+ responseText += `- 文本: ${info.text}\n`;
248
+ if (info?.disabled)
249
+ responseText += `- 状态: 禁用\n`;
250
+ return {
251
+ content: [{
252
+ type: 'text',
253
+ text: responseText,
254
+ }],
255
+ };
256
+ }
257
+ else {
258
+ return {
259
+ content: [{
260
+ type: 'text',
261
+ text: `❌ 点击失败:${result.error || '未知错误'}`,
262
+ }],
263
+ };
264
+ }
265
+ }
266
+ throw new Error(`未知工具:${name}`);
267
+ });
268
+ // 启动服务器
269
+ async function main() {
270
+ const transport = new StdioServerTransport();
271
+ await server.connect(transport);
272
+ console.error('MCP Server 已启动,等待连接...');
273
+ }
274
+ main().catch((error) => {
275
+ console.error('服务器启动失败:', error);
276
+ process.exit(1);
277
+ });
278
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { ClickElementResult } from '../types/index.js';
2
+ export declare function clickElement(url: string, selector: string, useExistingPage?: boolean): Promise<ClickElementResult>;
3
+ //# sourceMappingURL=click-element.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"click-element.d.ts","sourceRoot":"","sources":["../../src/tools/click-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAIvD,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,eAAe,GAAE,OAAc,GAC9B,OAAO,CAAC,kBAAkB,CAAC,CA2L7B"}
@@ -0,0 +1,166 @@
1
+ import { getBrowser, getPage, closeBrowser } from '../utils/browser.js';
2
+ // 点击页面元素
3
+ export async function clickElement(url, selector, useExistingPage = true) {
4
+ let browserConnection = null;
5
+ try {
6
+ // 获取浏览器实例
7
+ browserConnection = await getBrowser();
8
+ const { browser, useExistingBrowser } = browserConnection;
9
+ // 获取页面
10
+ const page = await getPage(browser, useExistingBrowser, useExistingPage ? 'current' : url);
11
+ // 如果需要导航到指定 URL
12
+ if (!useExistingPage && url !== 'current') {
13
+ await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
14
+ }
15
+ console.error(`正在查找元素: ${selector}`);
16
+ // 首先尝试使用 page.evaluate 直接查找元素(更可靠)
17
+ const elementInfo = await page.evaluate((sel) => {
18
+ // 尝试多种选择器方式
19
+ let element = null;
20
+ // 1. 直接尝试 CSS 选择器
21
+ try {
22
+ element = document.querySelector(sel);
23
+ }
24
+ catch (e) {
25
+ // 选择器语法错误,继续尝试其他方式
26
+ }
27
+ // 2. 如果是 href 包含选择器,尝试通过属性查找
28
+ if (!element && sel.includes('[href')) {
29
+ const match = sel.match(/href\*?="?([^"\]]*)"?\]/);
30
+ if (match) {
31
+ const hrefValue = match[1];
32
+ const links = document.querySelectorAll('a');
33
+ for (const link of Array.from(links)) {
34
+ if (link.href && link.href.includes(hrefValue)) {
35
+ element = link;
36
+ break;
37
+ }
38
+ }
39
+ }
40
+ }
41
+ // 3. 如果是类名选择器,尝试通过类名查找
42
+ if (!element && sel.startsWith('.')) {
43
+ const className = sel.substring(1);
44
+ const elements = document.querySelectorAll('*');
45
+ for (const el of Array.from(elements)) {
46
+ if (el.className && el.className.includes && el.className.includes(className)) {
47
+ element = el;
48
+ break;
49
+ }
50
+ }
51
+ }
52
+ // 4. 如果是文本内容选择器,尝试通过文本查找
53
+ if (!element && sel.includes(':contains')) {
54
+ const match = sel.match(/:contains\(["']?([^"']*)["']?\)/);
55
+ if (match) {
56
+ const text = match[1];
57
+ const allElements = document.querySelectorAll('*');
58
+ for (const el of Array.from(allElements)) {
59
+ if (el.textContent && el.textContent.trim() === text) {
60
+ element = el;
61
+ break;
62
+ }
63
+ }
64
+ }
65
+ }
66
+ if (!element) {
67
+ return null;
68
+ }
69
+ // 获取元素信息
70
+ return {
71
+ tagName: element.tagName.toLowerCase(),
72
+ type: element.getAttribute('type') || undefined,
73
+ name: element.getAttribute('name') || undefined,
74
+ id: element.id || undefined,
75
+ className: element.className || undefined,
76
+ text: element.textContent?.trim() || undefined,
77
+ disabled: element.disabled || false,
78
+ foundSelector: sel
79
+ };
80
+ }, selector);
81
+ if (!elementInfo) {
82
+ await closeBrowser(browser, useExistingBrowser, true);
83
+ return {
84
+ success: false,
85
+ error: `未找到元素: ${selector}`
86
+ };
87
+ }
88
+ // 使用 page.evaluate 点击元素(更可靠)
89
+ const clickResult = await page.evaluate((sel) => {
90
+ // 重新查找元素并点击
91
+ let element = null;
92
+ // 同样的查找逻辑
93
+ try {
94
+ element = document.querySelector(sel);
95
+ }
96
+ catch (e) { }
97
+ if (!element && sel.includes('[href')) {
98
+ const match = sel.match(/href\*?="?([^"\]]*)"?\]/);
99
+ if (match) {
100
+ const hrefValue = match[1];
101
+ const links = document.querySelectorAll('a');
102
+ for (const link of Array.from(links)) {
103
+ if (link.href && link.href.includes(hrefValue)) {
104
+ element = link;
105
+ break;
106
+ }
107
+ }
108
+ }
109
+ }
110
+ if (!element && sel.startsWith('.')) {
111
+ const className = sel.substring(1);
112
+ const elements = document.querySelectorAll('*');
113
+ for (const el of Array.from(elements)) {
114
+ if (el.className && el.className.includes && el.className.includes(className)) {
115
+ element = el;
116
+ break;
117
+ }
118
+ }
119
+ }
120
+ if (element) {
121
+ // 滚动到元素可见
122
+ element.scrollIntoView({ behavior: 'smooth', block: 'center' });
123
+ // 模拟点击
124
+ const clickEvent = new MouseEvent('click', {
125
+ bubbles: true,
126
+ cancelable: true,
127
+ view: window
128
+ });
129
+ element.dispatchEvent(clickEvent);
130
+ // 也尝试原生点击
131
+ if (element.click) {
132
+ element.click();
133
+ }
134
+ return true;
135
+ }
136
+ return false;
137
+ }, selector);
138
+ if (!clickResult) {
139
+ await closeBrowser(browser, useExistingBrowser, true);
140
+ return {
141
+ success: false,
142
+ error: `点击元素失败: ${selector}`
143
+ };
144
+ }
145
+ console.error(`成功点击元素: ${elementInfo.tagName}`);
146
+ // 保持浏览器打开
147
+ await closeBrowser(browser, useExistingBrowser, true);
148
+ return {
149
+ success: true,
150
+ elementInfo
151
+ };
152
+ }
153
+ catch (error) {
154
+ console.error('点击元素失败:', error);
155
+ // 发生错误时保持浏览器打开
156
+ if (browserConnection) {
157
+ const { browser, useExistingBrowser } = browserConnection;
158
+ await closeBrowser(browser, useExistingBrowser, true);
159
+ }
160
+ return {
161
+ success: false,
162
+ error: error.message || '未知错误'
163
+ };
164
+ }
165
+ }
166
+ //# sourceMappingURL=click-element.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"click-element.js","sourceRoot":"","sources":["../../src/tools/click-element.ts"],"names":[],"mappings":"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"}