rpa 任务编排
xml



<?xml version="1.0" encoding="utf-8"?> <repository xmlns:x="rpa://selector/core" xmlns:regex="rpa://selector/operator/regex" xmlns:wildcard="rpa://selector/operator/wildcard" xmlns:contains="rpa://selector/operator/contains" xmlns:notContains="rpa://selector/operator/notContains" xmlns:startsWith="rpa://selector/operator/startsWith" xmlns:notStartsWith="rpa://selector/operator/notStartsWith" xmlns:endsWith="rpa://selector/operator/endsWith" xmlns:notEndsWith="rpa://selector/operator/notEndsWith" xmlns:notEquals="rpa://selector/operator/notEquals" xmlns:greaterThan="rpa://selector/operator/greaterThan" xmlns:greaterThanOrEqual="rpa://selector/operator/greaterThanOrEqual" xmlns:lessThan="rpa://selector/operator/lessThan" xmlns:lessThanOrEqual="rpa://selector/operator/lessThanOrEqual"> <group id="378806ed-df52-4b4c-a7b3-1c85576bcd6a" name="影刀RPA - 影刀官网" type="Web" processName="chrome" icon=".dev\icon\0897ae0c-d077-4be7-9ad1-b51ade5872b4.png" criteria="https://www.yingdao.com" selectorOringin="Inspect"> <selector id="50a15322-17bc-4050-8431-e8a6ab7df07b" name="姓名" type="simple" framework="chrome" selectorOringin="Inspect" processName="chrome" productName="Google Chrome" winTitle="影刀RPA - 影刀官网" screenshot=".dev\screenshot\33914c42-48a9-44ea-a80f-ae5fb405aa9c.jpg" version="2"> <web x:name="div" x:selected="false"> <optional id="root" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional class="layout___3kS5z" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional class="message___3jpIK" index-of-type="2" index="2" /> </web> <web x:name="div" x:selected="false"> <optional class="messageBanner___8FYNF" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional class="messageBannerContent___30_I0" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional class="bannerRight___1Nq5A" index-of-type="1" index="1" /> </web> <web x:name="form"> <optional class="ant-form ant-form-vertical contentRightForm___20vzk" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional class="ant-form-item ant-form-item-with-help ant-form-item-has-error" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional class="ant-row ant-form-item-row" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional innerText="请输入姓名" class="ant-col ant-form-item-control" index-of-type="1" index="1" /> </web> <web x:name="div" x:selected="false"> <optional class="ant-form-item-control-input" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional class="ant-form-item-control-input-content" index-of-type="0" index="0" /> </web> <web x:name="input" id="name"> <optional type="text" class="ant-input ant-input-status-error" index-of-type="0" placeholder="请输入姓名" aria-required="true" aria-describedby="name_help" aria-invalid="true" index="0" /> </web> <anchor text="姓名" targetRectangle="[740,243,396,41]" anchorRectangle="[740,215,39,20]" version="1" threshold="0.85" /> <semantic status="disabled" image="https://winrobot-pub-a.oss-cn-hangzhou.aliyuncs.com/966969883689275394/file/client/element/e4600cc14891798222bb6c2e41bf5bb96a31fccf7e701856ca2ff039b7dccbe2_semantic_False.png" rectangle="[714,355,382,59]" desc="" /> </selector> <selector id="ca58a85f-3d69-4459-b45d-99d6f58fc11c" name="手机号" type="simple" framework="chrome" selectorOringin="Inspect" processName="chrome" productName="Google Chrome" winTitle="影刀RPA - 影刀官网" screenshot=".dev\screenshot\3b7515e5-b1dc-42b9-8b2b-c197cb515653.jpg" version="2"> <web x:name="div" x:selected="false"> <optional id="root" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional class="layout___3kS5z" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional class="message___3jpIK" index-of-type="2" index="2" /> </web> <web x:name="div" x:selected="false"> <optional class="messageBanner___8FYNF" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional class="messageBannerContent___30_I0" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional class="bannerRight___1Nq5A" index-of-type="1" index="1" /> </web> <web x:name="form"> <optional class="ant-form ant-form-vertical contentRightForm___20vzk" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional class="ant-form-item ant-form-item-with-help ant-form-item-has-error" index-of-type="1" index="1" /> </web> <web x:name="div" x:selected="false"> <optional class="ant-row ant-form-item-row" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional innerText="请输入手机号" class="ant-col ant-form-item-control" index-of-type="1" index="1" /> </web> <web x:name="div" x:selected="false"> <optional class="ant-form-item-control-input" index-of-type="0" index="0" /> </web> <web x:name="div" x:selected="false"> <optional class="ant-form-item-control-input-content" index-of-type="0" index="0" /> </web> <web x:name="input" id="number"> <optional type="text" class="ant-input ant-input-status-error" index-of-type="0" placeholder="请输入手机号" aria-required="true" aria-describedby="number_help" aria-invalid="true" index="0" /> </web> <anchor text="手机号" targetRectangle="[740,338,396,41]" anchorRectangle="[740,310,53,20]" version="1" threshold="0.85" /> <semantic status="disabled" image="https://winrobot-pub-a.oss-cn-hangzhou.aliyuncs.com/966969883689275394/file/client/element/bf2514812ef472c277bbbf3cf6c860e5f99b2715f5f60d088987de44592af910_semantic_False.png" rectangle="[714,495,382,59]" desc="" /> </selector> </group> </repository>
新闻列表
(() => {
const items = [];
const seen = new Set();
const links = [...document.querySelectorAll("a[href*='/news/']")];
for (const a of links) {
const href = (a.getAttribute("href") || "").trim();
if (!href || /\/news\/?$/.test(href.replace(location.origin, ""))) continue;
const title = (a.innerText || a.textContent || "")
.trim()
.replace(/\s+/g, " ");
if (!title || title.length < 4 || title === "查看更多") continue;
if (seen.has(title)) continue;
seen.add(title);
items.push({ title, href });
}
const titles = items.map((item) => item.title);
return {
href: location.href,
title: document.title,
newsLinkCount: items.length,
newsTitles: titles,
newsItems: items,
domNodeCount: document.querySelectorAll(
"[class*='news'], [class*='News'], article, li"
).length,
bodyHeight: document.body?.scrollHeight || 0,
};
})()
https://www.yingdao.com/news/
(() => {
const normalize = (text) => (text || "").replace(/\s+/g, "");
const nodes = [...document.querySelectorAll("a, button, [role='button'], div, span, p")];
const target = nodes.find((el) => {
const text = normalize(el.textContent);
return text === "查看更多" || (text.includes("查看更多") && text.length <= 24);
});
if (!target) {
return { ok: false, reason: "not_found" };
}
target.scrollIntoView({ block: "center", behavior: "instant" });
target.click();
return {
ok: true,
tag: target.tagName,
text: (target.textContent || "").trim().slice(0, 80),
};
})()
{ok: true, tag: 'DIV', text: '查看更多'}
控制台里 DOM 点击仍可能无效,这是浏览器安全机制,不是脚本写错。
// 定位「查看更多」并尝试 DOM 点击;返回中心坐标 (x,y) 供 CDP Input 可信点击。
// 注意:控制台执行时 dispatchEvent/.click() 的 isTrusted=false,部分站点会无效果。
(() => {
const normalize = (text) => (text || "").replace(/\s+/g, "");
const isViewMore = (text) =>
text === "查看更多" || (text.includes("查看更多") && text.length <= 24);
const candidates = [...document.querySelectorAll("*")].filter((el) => {
const text = normalize(el.textContent);
if (!isViewMore(text)) return false;
const rect = el.getBoundingClientRect();
return rect.width > 0 && rect.height > 0;
});
if (!candidates.length) {
return { ok: false, reason: "not_found" };
}
// 取文本最短的节点,避免点到外层大容器 DIV
candidates.sort(
(a, b) => normalize(a.textContent).length - normalize(b.textContent).length
);
const pickClickTarget = (el) => {
let node = el;
while (node && node !== document.documentElement) {
const tag = node.tagName;
const role = node.getAttribute?.("role");
const style = window.getComputedStyle(node);
if (
tag === "A" ||
tag === "BUTTON" ||
role === "button" ||
node.hasAttribute("onclick") ||
style.cursor === "pointer"
) {
return node;
}
node = node.parentElement;
}
return el;
};
const dispatchMouseClick = (el, x, y) => {
const base = {
bubbles: true,
cancelable: true,
view: window,
clientX: x,
clientY: y,
button: 0,
buttons: 1,
};
for (const type of ["pointerdown", "mousedown", "pointerup", "mouseup", "click"]) {
const EventClass = type.startsWith("pointer") ? PointerEvent : MouseEvent;
el.dispatchEvent(new EventClass(type, base));
}
if (typeof el.click === "function") {
el.click();
}
};
const base = candidates[0];
const target = pickClickTarget(base);
target.scrollIntoView({ block: "center", behavior: "instant" });
const rect = target.getBoundingClientRect();
if (rect.width <= 0 || rect.height <= 0) {
return { ok: false, reason: "not_visible", tag: target.tagName };
}
const x = rect.left + rect.width / 2;
const y = rect.top + rect.height / 2;
// 控制台里 dispatchEvent / .click() 可能是 isTrusted=false,部分站点会忽略
dispatchMouseClick(target, x, y);
return {
ok: true,
tag: target.tagName,
baseTag: base.tagName,
text: (target.textContent || "").trim().slice(0, 80),
className: String(target.className || "").slice(0, 120),
x: Math.round(x),
y: Math.round(y),
};
})()

浙公网安备 33010602011771号