@acedatacloud/skills 2026.714.3 → 2026.715.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 (29) hide show
  1. package/package.json +1 -1
  2. package/skills/telegram/SKILL.md +20 -6
  3. package/skills/telegram/scripts/tg.py +34 -3
  4. package/skills/xiaohongshu/SKILL.md +76 -136
  5. package/skills/xiaohongshu/tests/test_browser_contract.py +79 -0
  6. package/skills/xiaohongshu/README.md +0 -36
  7. package/skills/xiaohongshu/requirements.txt +0 -1
  8. package/skills/xiaohongshu/scripts/vendor/LICENSE.autoclaw-xiaohongshu-skills +0 -21
  9. package/skills/xiaohongshu/scripts/vendor/title_utils.py +0 -57
  10. package/skills/xiaohongshu/scripts/vendor/xhs/__init__.py +0 -1
  11. package/skills/xiaohongshu/scripts/vendor/xhs/cdp.py +0 -940
  12. package/skills/xiaohongshu/scripts/vendor/xhs/comment.py +0 -283
  13. package/skills/xiaohongshu/scripts/vendor/xhs/errors.py +0 -92
  14. package/skills/xiaohongshu/scripts/vendor/xhs/feed_detail.py +0 -550
  15. package/skills/xiaohongshu/scripts/vendor/xhs/feeds.py +0 -49
  16. package/skills/xiaohongshu/scripts/vendor/xhs/human.py +0 -79
  17. package/skills/xiaohongshu/scripts/vendor/xhs/like_favorite.py +0 -188
  18. package/skills/xiaohongshu/scripts/vendor/xhs/login.py +0 -377
  19. package/skills/xiaohongshu/scripts/vendor/xhs/publish.py +0 -1208
  20. package/skills/xiaohongshu/scripts/vendor/xhs/publish_long_article.py +0 -293
  21. package/skills/xiaohongshu/scripts/vendor/xhs/publish_video.py +0 -183
  22. package/skills/xiaohongshu/scripts/vendor/xhs/search.py +0 -226
  23. package/skills/xiaohongshu/scripts/vendor/xhs/selectors.py +0 -97
  24. package/skills/xiaohongshu/scripts/vendor/xhs/stealth.py +0 -316
  25. package/skills/xiaohongshu/scripts/vendor/xhs/types.py +0 -473
  26. package/skills/xiaohongshu/scripts/vendor/xhs/urls.py +0 -30
  27. package/skills/xiaohongshu/scripts/vendor/xhs/user_profile.py +0 -111
  28. package/skills/xiaohongshu/scripts/xiaohongshu.py +0 -1182
  29. package/skills/xiaohongshu/tests/test_xiaohongshu.py +0 -967
@@ -1,97 +0,0 @@
1
- """小红书页面 CSS 选择器常量。"""
2
-
3
- # ========== 登录 ==========
4
- LOGIN_STATUS = ".main-container .user .link-wrapper .channel"
5
- QRCODE_IMG = ".qrcode-img"
6
-
7
- # ========== 手机号登录 ==========
8
- LOGIN_CONTAINER = ".login-container"
9
- PHONE_INPUT = "label.phone input"
10
- GET_CODE_BUTTON = "span.code-button"
11
- CODE_INPUT = "label.auth-code input"
12
- PHONE_LOGIN_SUBMIT = ".input-container button.submit"
13
- AGREE_CHECKBOX = ".agree-icon .icon-wrapper"
14
- AGREE_CHECKBOX_CHECKED = ".agree-icon .icon-wrapper.agreed"
15
- LOGIN_ERR_MSG = ".err-msg"
16
-
17
- # ========== 首页 / 搜索 ==========
18
- FILTER_BUTTON = "div.filter"
19
- FILTER_PANEL = "div.filters-wrapper"
20
-
21
- # ========== Feed 详情 ==========
22
- COMMENTS_CONTAINER = ".comments-container"
23
- PARENT_COMMENT = ".parent-comment, .comment-item"
24
- NO_COMMENTS_TEXT = ".no-comments-text"
25
- END_CONTAINER = ".end-container"
26
- TOTAL_COMMENT = ".comments-container .total"
27
- SHOW_MORE_BUTTON = ".show-more"
28
- NOTE_SCROLLER = ".note-scroller"
29
- INTERACTION_CONTAINER = ".interaction-container"
30
-
31
- # 页面不可访问容器
32
- ACCESS_ERROR_WRAPPER = ".access-wrapper, .error-wrapper, .not-found-wrapper, .blocked-wrapper"
33
-
34
- # ========== 评论输入 ==========
35
- COMMENT_INPUT_TRIGGER = "div.input-box div.content-edit span"
36
- COMMENT_INPUT_FIELD = "div.input-box div.content-edit p.content-input"
37
- COMMENT_SUBMIT_BUTTON = "div.bottom button.submit"
38
- REPLY_BUTTON = ".right .interactions .reply"
39
-
40
- # ========== 点赞 / 收藏 ==========
41
- LIKE_BUTTON = ".interact-container .left .like-lottie"
42
- COLLECT_BUTTON = ".interact-container .left .reds-icon.collect-icon"
43
-
44
- # ========== 发布页 ==========
45
- UPLOAD_CONTENT = "div.upload-content"
46
- CREATOR_TAB = "div.creator-tab"
47
- UPLOAD_INPUT = ".upload-input"
48
- FILE_INPUT = 'input[type="file"]'
49
- TITLE_INPUT = "div.d-input input"
50
- CONTENT_EDITOR = 'div.tiptap.ProseMirror[contenteditable="true"], div.ql-editor'
51
- IMAGE_PREVIEW = ".img-preview-area .pr"
52
- PUBLISH_BUTTON = ".publish-page-publish-btn button.bg-red"
53
-
54
- # 标题/正文长度校验
55
- TITLE_MAX_SUFFIX = "div.title-container div.max_suffix"
56
- CONTENT_LENGTH_ERROR = "div.edit-container div.length-error"
57
-
58
- # 可见范围
59
- VISIBILITY_DROPDOWN = "div.permission-card-wrapper div.d-select-content"
60
- VISIBILITY_OPTIONS = "div.d-options-wrapper div.d-grid-item div.custom-option"
61
-
62
- # 定时发布
63
- SCHEDULE_SWITCH = ".post-time-wrapper .d-switch"
64
- DATETIME_INPUT = ".date-picker-container input"
65
-
66
- # 原创声明
67
- ORIGINAL_SWITCH_CARD = "div.custom-switch-card"
68
- ORIGINAL_SWITCH = "div.d-switch"
69
-
70
- # 标签联想
71
- TAG_TOPIC_CONTAINER = "#creator-editor-topic-container"
72
- TAG_FIRST_ITEM = ".item"
73
-
74
- # 弹窗
75
- POPOVER = "div.d-popover"
76
-
77
- # ========== 写长文模式 ==========
78
- # 注意: 长文模式的按钮(写长文、新的创作、一键排版、下一步)通过文本匹配定位
79
- LONG_ARTICLE_TAB_TEXT = "写长文"
80
- NEW_CREATION_BUTTON_TEXT = "新的创作"
81
- AUTO_FORMAT_BUTTON_TEXT = "一键排版"
82
- NEXT_STEP_BUTTON_TEXT = "下一步"
83
-
84
- LONG_ARTICLE_TITLE = 'textarea.d-text[placeholder="输入标题"]'
85
- TEMPLATE_CARD = ".template-card"
86
- TEMPLATE_TITLE = ".template-card .template-title"
87
-
88
- # ========== 退出登录 ==========
89
- LOGOUT_MORE_BUTTON = "div.information-wrapper"
90
- LOGOUT_MENU_ITEM = 'div.menu-item[data-name="退出登录"]'
91
-
92
- # ========== 用户主页 ==========
93
- SIDEBAR_PROFILE = "div.main-container li.user.side-bar-component a.link-wrapper span.channel"
94
- # 登录后导航栏"我"的链接(href 含 /user/profile/<user_id>)
95
- USER_PROFILE_NAV_LINK = ".main-container .user .link-wrapper a.link-wrapper"
96
- # 个人主页真实昵称
97
- USER_NICKNAME = ".user-name"
@@ -1,316 +0,0 @@
1
- """反检测配置:UA / Client Hints / JS 注入 / Chrome 启动参数。
2
-
3
- 关键原则:UA、navigator.platform、Client Hints、WebGL 等所有信号必须与实际平台一致。
4
- """
5
-
6
- from __future__ import annotations
7
-
8
- import platform as _platform
9
-
10
- # Chrome 版本号 — 定期更新以匹配主流版本(当前对应 2025 年中期稳定版)
11
- _CHROME_VER = "136"
12
- _CHROME_FULL_VER = "136.0.0.0"
13
-
14
-
15
- def _build_platform_config() -> dict:
16
- """根据实际操作系统生成一致的 UA / Client Hints / WebGL 配置。"""
17
- system = _platform.system()
18
-
19
- brands = [
20
- {"brand": "Chromium", "version": _CHROME_VER},
21
- {"brand": "Google Chrome", "version": _CHROME_VER},
22
- {"brand": "Not-A.Brand", "version": "24"},
23
- ]
24
- full_version_list = [
25
- {"brand": "Chromium", "version": _CHROME_FULL_VER},
26
- {"brand": "Google Chrome", "version": _CHROME_FULL_VER},
27
- {"brand": "Not-A.Brand", "version": "24.0.0.0"},
28
- ]
29
-
30
- if system == "Darwin":
31
- arch = "arm" if _platform.machine() == "arm64" else "x86"
32
- return {
33
- "ua": (
34
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
35
- "AppleWebKit/537.36 (KHTML, like Gecko) "
36
- f"Chrome/{_CHROME_FULL_VER} Safari/537.36"
37
- ),
38
- "nav_platform": "MacIntel",
39
- "ua_metadata": {
40
- "brands": brands,
41
- "fullVersionList": full_version_list,
42
- "platform": "macOS",
43
- "platformVersion": "14.5.0",
44
- "architecture": arch,
45
- "model": "",
46
- "mobile": False,
47
- "bitness": "64",
48
- "wow64": False,
49
- },
50
- "webgl_vendor": "Apple Inc.",
51
- "webgl_renderer": (
52
- "ANGLE (Apple, ANGLE Metal Renderer: Apple M1, Unspecified Version)"
53
- ),
54
- }
55
-
56
- if system == "Windows":
57
- return {
58
- "ua": (
59
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
60
- "AppleWebKit/537.36 (KHTML, like Gecko) "
61
- f"Chrome/{_CHROME_FULL_VER} Safari/537.36"
62
- ),
63
- "nav_platform": "Win32",
64
- "ua_metadata": {
65
- "brands": brands,
66
- "fullVersionList": full_version_list,
67
- "platform": "Windows",
68
- "platformVersion": "15.0.0",
69
- "architecture": "x86",
70
- "model": "",
71
- "mobile": False,
72
- "bitness": "64",
73
- "wow64": False,
74
- },
75
- "webgl_vendor": "Google Inc. (Intel)",
76
- "webgl_renderer": (
77
- "ANGLE (Intel, Intel(R) UHD Graphics 630 (CML GT2), Direct3D11)"
78
- ),
79
- }
80
-
81
- # Linux
82
- return {
83
- "ua": (
84
- "Mozilla/5.0 (X11; Linux x86_64) "
85
- "AppleWebKit/537.36 (KHTML, like Gecko) "
86
- f"Chrome/{_CHROME_FULL_VER} Safari/537.36"
87
- ),
88
- "nav_platform": "Linux x86_64",
89
- "ua_metadata": {
90
- "brands": brands,
91
- "fullVersionList": full_version_list,
92
- "platform": "Linux",
93
- "platformVersion": "6.5.0",
94
- "architecture": "x86",
95
- "model": "",
96
- "mobile": False,
97
- "bitness": "64",
98
- "wow64": False,
99
- },
100
- "webgl_vendor": "Google Inc. (Mesa)",
101
- "webgl_renderer": (
102
- "ANGLE (Mesa, Mesa Intel(R) UHD Graphics 630 (CML GT2), OpenGL 4.6)"
103
- ),
104
- }
105
-
106
-
107
- PLATFORM_CONFIG = _build_platform_config()
108
-
109
- # 向后兼容导出
110
- REALISTIC_UA = PLATFORM_CONFIG["ua"]
111
-
112
-
113
- def build_ua_override(chrome_full_ver: str | None = None) -> dict:
114
- """构建 Emulation.setUserAgentOverride 参数。
115
-
116
- Args:
117
- chrome_full_ver: Chrome 完整版本号(如 "134.0.6998.88"),
118
- 从 CDP /json/version 接口获取。为 None 时使用默认值。
119
-
120
- Returns:
121
- 可直接传给 Emulation.setUserAgentOverride 的参数字典。
122
- """
123
- ver = chrome_full_ver or _CHROME_FULL_VER
124
- major = ver.split(".")[0]
125
- system = _platform.system()
126
-
127
- brands = [
128
- {"brand": "Chromium", "version": major},
129
- {"brand": "Google Chrome", "version": major},
130
- {"brand": "Not-A.Brand", "version": "24"},
131
- ]
132
- full_version_list = [
133
- {"brand": "Chromium", "version": ver},
134
- {"brand": "Google Chrome", "version": ver},
135
- {"brand": "Not-A.Brand", "version": "24.0.0.0"},
136
- ]
137
-
138
- if system == "Darwin":
139
- arch = "arm" if _platform.machine() == "arm64" else "x86"
140
- ua = (
141
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
142
- "AppleWebKit/537.36 (KHTML, like Gecko) "
143
- f"Chrome/{ver} Safari/537.36"
144
- )
145
- nav_platform = "MacIntel"
146
- ua_platform = "macOS"
147
- platform_ver = "14.5.0"
148
- elif system == "Windows":
149
- arch = "x86"
150
- ua = (
151
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
152
- "AppleWebKit/537.36 (KHTML, like Gecko) "
153
- f"Chrome/{ver} Safari/537.36"
154
- )
155
- nav_platform = "Win32"
156
- ua_platform = "Windows"
157
- platform_ver = "15.0.0"
158
- else:
159
- arch = "x86"
160
- ua = (
161
- "Mozilla/5.0 (X11; Linux x86_64) "
162
- "AppleWebKit/537.36 (KHTML, like Gecko) "
163
- f"Chrome/{ver} Safari/537.36"
164
- )
165
- nav_platform = "Linux x86_64"
166
- ua_platform = "Linux"
167
- platform_ver = "6.5.0"
168
-
169
- return {
170
- "userAgent": ua,
171
- "platform": nav_platform,
172
- "userAgentMetadata": {
173
- "brands": brands,
174
- "fullVersionList": full_version_list,
175
- "platform": ua_platform,
176
- "platformVersion": platform_ver,
177
- "architecture": arch,
178
- "model": "",
179
- "mobile": False,
180
- "bitness": "64",
181
- "wow64": False,
182
- },
183
- }
184
-
185
- # ---------------------------------------------------------------------------
186
- # 反检测 JS 脚本模板($$占位符$$ 由 Python 替换为平台值)
187
- # ---------------------------------------------------------------------------
188
- _STEALTH_JS_TEMPLATE = """
189
- (() => {
190
- // 1. navigator.webdriver — Proxy 包装原始 native getter,toString() 仍返回 [native code]
191
- const wd = Object.getOwnPropertyDescriptor(Navigator.prototype, 'webdriver');
192
- if (wd && wd.get) {
193
- Object.defineProperty(Navigator.prototype, 'webdriver', {
194
- get: new Proxy(wd.get, { apply: () => false }),
195
- configurable: true,
196
- });
197
- }
198
-
199
- // 2. chrome.runtime
200
- if (!window.chrome) window.chrome = {};
201
- if (!window.chrome.runtime) {
202
- window.chrome.runtime = { connect: () => {}, sendMessage: () => {} };
203
- }
204
-
205
- // 3. chrome.app — headless 缺失此对象,检测脚本会检查
206
- if (!window.chrome.app) {
207
- window.chrome.app = {
208
- isInstalled: false,
209
- InstallState: {
210
- DISABLED: 'disabled',
211
- INSTALLED: 'installed',
212
- NOT_INSTALLED: 'not_installed',
213
- },
214
- RunningState: {
215
- CANNOT_RUN: 'cannot_run',
216
- READY_TO_RUN: 'ready_to_run',
217
- RUNNING: 'running',
218
- },
219
- getDetails: function() {},
220
- getIsInstalled: function() {},
221
- installState: function() { return 'not_installed'; },
222
- runningState: function() { return 'cannot_run'; },
223
- };
224
- }
225
-
226
- // 4. navigator.vendor — Chrome 应返回 "Google Inc."
227
- Object.defineProperty(navigator, 'vendor', {
228
- get: () => 'Google Inc.',
229
- configurable: true,
230
- });
231
-
232
- // 5. plugins — 不覆盖,真实 Chrome 已有正确的 PluginArray
233
-
234
- // 4. languages
235
- Object.defineProperty(navigator, 'languages', {
236
- get: () => ['zh-CN', 'zh', 'en-US', 'en'],
237
- configurable: true,
238
- });
239
-
240
- // 5. permissions
241
- const originalQuery = window.navigator.permissions?.query;
242
- if (originalQuery) {
243
- window.navigator.permissions.query = (parameters) =>
244
- parameters.name === 'notifications'
245
- ? Promise.resolve({ state: Notification.permission })
246
- : originalQuery(parameters);
247
- }
248
-
249
- // 6. WebGL vendor/renderer — 与平台一致(同时覆盖 WebGL1 和 WebGL2)
250
- const overrideWebGL = (proto) => {
251
- const original = proto.getParameter;
252
- proto.getParameter = function(p) {
253
- if (p === 37445) return '$$WEBGL_VENDOR$$';
254
- if (p === 37446) return '$$WEBGL_RENDERER$$';
255
- return original.call(this, p);
256
- };
257
- };
258
- overrideWebGL(WebGLRenderingContext.prototype);
259
- if (typeof WebGL2RenderingContext !== 'undefined') {
260
- overrideWebGL(WebGL2RenderingContext.prototype);
261
- }
262
-
263
- // 7. hardwareConcurrency — 随机 4 或 8
264
- Object.defineProperty(navigator, 'hardwareConcurrency', {
265
- get: () => [4, 8][Math.floor(Math.random() * 2)],
266
- configurable: true,
267
- });
268
-
269
- // 8. deviceMemory — 随机 4 或 8
270
- Object.defineProperty(navigator, 'deviceMemory', {
271
- get: () => [4, 8][Math.floor(Math.random() * 2)],
272
- configurable: true,
273
- });
274
-
275
- // 9. navigator.connection — 伪造网络信息
276
- Object.defineProperty(navigator, 'connection', {
277
- get: () => ({
278
- effectiveType: '4g',
279
- downlink: 10,
280
- rtt: 50,
281
- saveData: false,
282
- }),
283
- configurable: true,
284
- });
285
-
286
- // 10. chrome.csi / chrome.loadTimes — 空函数伪装
287
- if (window.chrome) {
288
- window.chrome.csi = function() { return {}; };
289
- window.chrome.loadTimes = function() { return {}; };
290
- }
291
-
292
- // 11. outerWidth/outerHeight — 不覆盖
293
- // 正常浏览器 outer > inner(有标题栏/工具栏),设为相等反而暴露自动化特征
294
-
295
- })();
296
- """
297
-
298
- STEALTH_JS = (
299
- _STEALTH_JS_TEMPLATE
300
- .replace("$$WEBGL_VENDOR$$", PLATFORM_CONFIG["webgl_vendor"])
301
- .replace("$$WEBGL_RENDERER$$", PLATFORM_CONFIG["webgl_renderer"])
302
- )
303
-
304
- # Chrome 启动参数(反检测相关)
305
- STEALTH_ARGS = [
306
- "--disable-blink-features=AutomationControlled",
307
- "--disable-infobars",
308
- "--no-first-run",
309
- "--no-default-browser-check",
310
- "--disable-background-timer-throttling",
311
- "--disable-backgrounding-occluded-windows",
312
- "--disable-renderer-backgrounding",
313
- "--disable-component-update",
314
- "--disable-extensions",
315
- "--disable-sync",
316
- ]