fix: 优化股票skill
This commit is contained in:
parent
51b01b9234
commit
cd7a27fd82
@ -22,6 +22,7 @@ argument-hint: "无需参数,直接调用即可"
|
|||||||
4. 网页上有这个类名(`topzs`)的 div 元素,展示了`上证指数`、`深证成指`、`创业板指`、`科创综指`、`北证50`的涨跌情况。优先截图这个元素,然后使用图像识别技能识别具体内容。
|
4. 网页上有这个类名(`topzs`)的 div 元素,展示了`上证指数`、`深证成指`、`创业板指`、`科创综指`、`北证50`的涨跌情况。优先截图这个元素,然后使用图像识别技能识别具体内容。
|
||||||
5. 网页上有这个 id(`stockmap`)的 div 元素,展示了各个板块的涨跌情况。如果用户想看板块涨跌情况,直接截图并使用发送图片技能发送图片。
|
5. 网页上有这个 id(`stockmap`)的 div 元素,展示了各个板块的涨跌情况。如果用户想看板块涨跌情况,直接截图并使用发送图片技能发送图片。
|
||||||
6. 如果没有获取到具体涨跌情况,则截图 id(`stockmap`) 的 div 元素并使用发送图片技能发送图片。
|
6. 如果没有获取到具体涨跌情况,则截图 id(`stockmap`) 的 div 元素并使用发送图片技能发送图片。
|
||||||
|
7. 调用 `web-page` 的 selector 截图模式时,`selector` 参数必须传真实 CSS 选择器字符串;当值以 `#` 开头时必须加引号,例如 `--selector '#stockmap'` 或 `--selector="#stockmap"`。
|
||||||
|
|
||||||
## 回复要求
|
## 回复要求
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import os from "node:os";
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { spawn, type ChildProcess } from "node:child_process";
|
import { spawn, type ChildProcess } from "node:child_process";
|
||||||
import type { IncomingMessage } from "node:http";
|
import type { IncomingMessage } from "node:http";
|
||||||
|
import { parseArgs as parseNodeArgs } from "node:util";
|
||||||
|
|
||||||
const DEFAULT_VIEWPORT_WIDTH = 1365;
|
const DEFAULT_VIEWPORT_WIDTH = 1365;
|
||||||
const DEFAULT_VIEWPORT_HEIGHT = 900;
|
const DEFAULT_VIEWPORT_HEIGHT = 900;
|
||||||
@ -47,7 +48,30 @@ type ActionType =
|
|||||||
| "scroll"
|
| "scroll"
|
||||||
| "scroll_to";
|
| "scroll_to";
|
||||||
|
|
||||||
type RawArgs = Record<string, string>;
|
type RawArgKey =
|
||||||
|
| "url"
|
||||||
|
| "mode"
|
||||||
|
| "screenshot_mode"
|
||||||
|
| "selector"
|
||||||
|
| "x"
|
||||||
|
| "y"
|
||||||
|
| "width"
|
||||||
|
| "height"
|
||||||
|
| "viewport_width"
|
||||||
|
| "viewport_height"
|
||||||
|
| "wait_ms"
|
||||||
|
| "timeout_ms"
|
||||||
|
| "max_chars"
|
||||||
|
| "max_full_height"
|
||||||
|
| "action_timeout_ms"
|
||||||
|
| "actions"
|
||||||
|
| "actions_file"
|
||||||
|
| "region_width"
|
||||||
|
| "region_height"
|
||||||
|
| "output"
|
||||||
|
| "send";
|
||||||
|
|
||||||
|
type RawArgs = Partial<Record<RawArgKey, string>>;
|
||||||
|
|
||||||
interface NormalizedAction {
|
interface NormalizedAction {
|
||||||
type: ActionType;
|
type: ActionType;
|
||||||
@ -139,33 +163,40 @@ function stdout(message: string): void {
|
|||||||
process.stdout.write(`${message}\n`);
|
process.stdout.write(`${message}\n`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseArgs(argv: string[]): RawArgs {
|
function parseCliArgs(argv: string[]): RawArgs {
|
||||||
const result: RawArgs = {};
|
try {
|
||||||
for (let index = 0; index < argv.length; index += 1) {
|
const parsed = parseNodeArgs({
|
||||||
const token = argv[index];
|
args: argv,
|
||||||
if (!token.startsWith("--")) {
|
allowPositionals: false,
|
||||||
throw new Error(`存在不支持的参数: ${token}`);
|
strict: true,
|
||||||
|
options: {
|
||||||
|
url: { type: "string" },
|
||||||
|
mode: { type: "string" },
|
||||||
|
screenshot_mode: { type: "string" },
|
||||||
|
selector: { type: "string" },
|
||||||
|
x: { type: "string" },
|
||||||
|
y: { type: "string" },
|
||||||
|
width: { type: "string" },
|
||||||
|
height: { type: "string" },
|
||||||
|
viewport_width: { type: "string" },
|
||||||
|
viewport_height: { type: "string" },
|
||||||
|
wait_ms: { type: "string" },
|
||||||
|
timeout_ms: { type: "string" },
|
||||||
|
max_chars: { type: "string" },
|
||||||
|
max_full_height: { type: "string" },
|
||||||
|
action_timeout_ms: { type: "string" },
|
||||||
|
actions: { type: "string" },
|
||||||
|
actions_file: { type: "string" },
|
||||||
|
region_width: { type: "string" },
|
||||||
|
region_height: { type: "string" },
|
||||||
|
output: { type: "string" },
|
||||||
|
send: { type: "string" },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return parsed.values as RawArgs;
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`命令行参数解析失败: ${errorMessage(error)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const equalIndex = token.indexOf("=");
|
|
||||||
let key = token.slice(2);
|
|
||||||
let value: string;
|
|
||||||
if (equalIndex >= 0) {
|
|
||||||
key = token.slice(2, equalIndex);
|
|
||||||
value = token.slice(equalIndex + 1);
|
|
||||||
} else {
|
|
||||||
const next = argv[index + 1];
|
|
||||||
if (next === undefined || next.startsWith("--")) {
|
|
||||||
value = "true";
|
|
||||||
} else {
|
|
||||||
value = next;
|
|
||||||
index += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result[key] = value;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseNumber(
|
function parseNumber(
|
||||||
@ -421,11 +452,12 @@ function normalizeParams(raw: RawArgs): Params {
|
|||||||
throw new Error("send 只能是 auto、true 或 false");
|
throw new Error("send 只能是 auto、true 或 false");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selector = (raw.selector || "").trim();
|
||||||
const params: Params = {
|
const params: Params = {
|
||||||
url,
|
url,
|
||||||
mode: mode as Params["mode"],
|
mode: mode as Params["mode"],
|
||||||
screenshotMode: screenshotMode as Params["screenshotMode"],
|
screenshotMode: screenshotMode as Params["screenshotMode"],
|
||||||
selector: raw.selector || "",
|
selector,
|
||||||
x: parseNumber(raw.x, "x"),
|
x: parseNumber(raw.x, "x"),
|
||||||
y: parseNumber(raw.y, "y"),
|
y: parseNumber(raw.y, "y"),
|
||||||
regionWidth: parseNumber(
|
regionWidth: parseNumber(
|
||||||
@ -1715,7 +1747,7 @@ async function maybeSendScreenshot(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function run(): Promise<void> {
|
||||||
const params = normalizeParams(parseArgs(process.argv.slice(2)));
|
const params = normalizeParams(parseCliArgs(process.argv.slice(2)));
|
||||||
const browser = await launchChromium(params);
|
const browser = await launchChromium(params);
|
||||||
const client = new CdpClient(browser.websocketUrl);
|
const client = new CdpClient(browser.websocketUrl);
|
||||||
try {
|
try {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user