{"id":19217497,"url":"https://github.com/lwdgit/chrome-automator","last_synced_at":"2025-07-14T08:03:40.292Z","repository":{"id":57198403,"uuid":"96950454","full_name":"lwdgit/chrome-automator","owner":"lwdgit","description":"Nightmare likely automator implemented by chrome-remote-interface.","archived":false,"fork":false,"pushed_at":"2017-10-21T12:27:00.000Z","size":10071,"stargazers_count":8,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-26T11:09:09.051Z","etag":null,"topics":["chrome-remote-interface","nightmarejs"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lwdgit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-12T01:03:01.000Z","updated_at":"2018-04-04T01:20:34.000Z","dependencies_parsed_at":"2022-09-16T14:10:26.419Z","dependency_job_id":null,"html_url":"https://github.com/lwdgit/chrome-automator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/lwdgit/chrome-automator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lwdgit%2Fchrome-automator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lwdgit%2Fchrome-automator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lwdgit%2Fchrome-automator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lwdgit%2Fchrome-automator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lwdgit","download_url":"https://codeload.github.com/lwdgit/chrome-automator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lwdgit%2Fchrome-automator/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265262187,"owners_count":23736407,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chrome-remote-interface","nightmarejs"],"created_at":"2024-11-09T14:22:31.601Z","updated_at":"2025-07-14T08:03:40.244Z","avatar_url":"https://github.com/lwdgit.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# chrome-automator\r\n\r\n基于 chrome-remote-interface 的自动化工具。\r\n\r\nAPI与 [Nightmare](https://github.com/segmentio/nightmare) 保持高度兼容。\r\n\r\n## Examples: (测试前请确保chrome版本大于60)\r\n\r\n```javascript\r\n  chrome({ show: true })\r\n  .viewport(1900, 1000)\r\n  .useragent('Mozilla/5.0 Chrome/59.0.3071.115 Mobile Safari/537.36')\r\n  .goto('https://www.baidu.com/')\r\n  .wait('body')\r\n  .insert('input#kw', 'hello world\\r')\r\n  .wait('.c-container a')\r\n  .click('.c-container a')\r\n  .wait('[id^=\"highlighter_\"]')\r\n  .screenshot('1.png')\r\n  .evaluate(() =\u003e document.querySelectorAll('.para-title.level-3')[9].nextElementSibling.querySelector('.code').textContent)\r\n  .pipe((code) =\u003e console.log(code))\r\n  .url()\r\n  .end()\r\n  .then((url) =\u003e console.log(url))\r\n```\r\n\r\n```javascript\r\nvar Nightmare = require('chrome-automator')\r\nNightmare.action('hello', function () {\r\n  console.log('Get url')\r\n  return this.evaluate_now(function () {\r\n    return document.querySelector('#links_wrapper a.result__a').href\r\n  })\r\n})\r\n\r\nvar nightmare = Nightmare({ show: true })\r\ntry {\r\n  nightmare\r\n  .goto('https://duckduckgo.com')\r\n  .type('#search_form_input_homepage', 'github nightmare')\r\n  .click('#search_button_homepage')\r\n  .wait('#zero_click_wrapper .c-info__title a')\r\n  .hello()\r\n  .end()\r\n  .then(function (result) {\r\n    console.log(result)\r\n  })\r\n} catch (e) {\r\n  console.log(e)\r\n}\r\n\r\n```\r\n\r\n## 命令行模式 (version \u003e= 0.2.0)\r\n\r\n```\r\n\u003e chrome-automator\r\n.chrome() // 启动chrome\r\n.goto('https://baidu.com')\r\n.goto{ frameId: '64607.1' }\r\n.insert('#kw', 'hello world\\r')\r\n.screenshot('1.jpg')\r\n.title()\r\n.end() // 关闭chrome\r\n```\r\n输出: hello world_百度搜索\r\n\r\n## API兼容列表如下:\r\n\r\n - [x] constructor 支持如下参数\r\n    - [x] port\r\n    - [x] show\r\n    - [x] chromePath\r\n    - [x] waitTimeout\r\n    - [x] executionTimeout\r\n    - [x] loadTimeout\r\n\r\n - [x] goto\r\n - [x] url\r\n - [x] title\r\n - [x] action 只支持 Promise 和 async 方式的异步写法，不支持 callback 方式\r\n - [x] evaluate\r\n - [x] click\r\n - [x] type\r\n - [x] insert\r\n - [x] wait\r\n - [x] mouseup\r\n - [x] mouseover\r\n - [x] mousedown\r\n - [x] check\r\n - [x] uncheck\r\n - [x] select\r\n - [x] scrollTo\r\n - [x] visible\r\n - [x] exists\r\n - [x] path\r\n - [x] back\r\n - [x] forward\r\n - [x] refresh\r\n - [x] end\r\n - [x] focusSelector\r\n - [x] blurSelector\r\n - [x] pdf 仅支持headless模式，设置 show: false 开启\r\n - [x] screenshot\r\n - [x] viewport\r\n - [x] useragent\r\n - [x] html\r\n - [x] authentication\r\n - [x] cookies\r\n    - [x] set\r\n    - [x] get\r\n    - [x] clear\r\n \r\n - [x] inject\r\n - [x] on 暂时支持的事件与Nightmare不同\r\n \u003cdetails\u003e\r\n \u003csummary\u003e列表如下: 详细说明见 https://chromedevtools.github.io/devtools-protocol/tot/Network/#event-loadingFailed \u003c/summary\u003e\r\n \r\n  - [x] Page.javascriptDialogOpening  弹窗事件\r\n  - [x] Console.messageAdded  旧console事件，不建议使用\r\n  - [x] Runtime.consoleAPICalled  console事件\r\n  \r\n  - [x] Network.resourceChangedPriority\r\n  - [x] Network.requestWillBeSent\r\n  - [x] Network.requestServedFromCache\r\n  - [x] Network.responseReceived\r\n  - [x] Network.dataReceived\r\n  - [x] Network.loadingFinished\r\n  - [x] Network.loadingFailed\r\n  - [x] Network.webSocketWillSendHandshakeRequest\r\n  - [x] Network.webSocketHandshakeResponseReceived\r\n  - [x] Network.webSocketCreated\r\n  - [x] Network.webSocketClosed\r\n  - [x] Network.webSocketFrameReceived\r\n  - [x] Network.webSocketFrameError\r\n  - [x] Network.webSocketFrameSent\r\n  - [x] Network.eventSourceMessageReceived\r\n  - [x] Network.requestIntercepted\r\n\r\n  - [x] Page.domContentEventFired\r\n  - [x] Page.loadEventFired\r\n  - [x] Page.frameAttached\r\n  - [x] Page.frameNavigated\r\n  - [x] Page.frameDetached\r\n  - [x] Page.frameStartedLoading\r\n  - [x] Page.frameStoppedLoading\r\n  - [x] Page.frameScheduledNavigation\r\n  - [x] Page.frameClearedScheduledNavigation\r\n  - [x] Page.frameResized\r\n  - [x] Page.javascriptDialogClosed\r\n  - [x] Page.screencastFrame\r\n  - [x] Page.screencastVisibilityChanged\r\n  - [x] Page.interstitialShown\r\n  - [x] Page.interstitialHidden\r\n\r\n \u003c/details\u003e\r\n\r\n \u003e 两种模式: \r\n  * 非阻塞式 默认方式，建议在 goto 之前使用\r\n  * 阻塞式，使用方式 `on(eventName, fn, { detach: false })`。 如想取消监听，可以 `return { cancled: true }` 继续接下来的流程。\r\n  例子见 [test4](./tests/test4.js)，[test5](./tests/test4.js)\r\n\r\n \r\n - [x] once 只监听事件一次，监听完成后可以继续后续的动作\r\n\r\n - [ ] halt 暂时不支持，chrome在此场景不太适用 https://github.com/segmentio/nightmare/issues/835\r\n - [ ] header 目前可以使用setExtraHTTPHeaders代替部分功能\r\n \r\n\r\n### 拓展功能及API:\r\n\r\n - [x] iframe 进入iframe，方便iframe里面的操作\r\n - [x] pipe 支持流程衔接，如登录流程，和 then 一样，pipe 也可以接收上个流程的返回值，建议在中间流程使用 pipe 替代 then\r\n - [x] 支持新窗口打开时自动跟踪，防控制跳失 注: headless模式下存在bug\r\n - [x] setExtraHTTPHeaders\r\n - [x] ignoreSWCache 忽略service worker缓存\r\n\r\n\u003e PS：目前原有框架(Nightmare)回调写法全部去除，仅保留 Promise 写法。\r\n\r\n\u003e Tips: 执行过程中手动进行某些操作（如打开开发者工具）可能会使用动作失效。\r\n\u003e 因为 Promise 无法取消的原因，所以在流程执行完 end 操作后node可能并不会立即退出，一般会在 30s 左右自动退出，可以缩短 loadTimeout 和 executionTimeout 解决\r\n\u003e Promise 异步流程目前在node下还无法显示完整的错误堆栈信息，可以考虑使用 `node --trace-warnings` 查看，也可以使用 `global.Promise = require('bluebird')`解决，使用过程中记得使用 try catch 包裹执行段\r\n\r\n\r\n## LICENSE\r\n\r\nMIT\r\n\r\n## 感谢\r\n \r\n * Nightmare\r\n * chrome-remote-interface\r\n * lighthouse\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flwdgit%2Fchrome-automator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flwdgit%2Fchrome-automator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flwdgit%2Fchrome-automator/lists"}