├── README.md
├── LICENSE
└── docs
└── api.md
/README.md:
--------------------------------------------------------------------------------
1 | # Puppeteer [](https://travis-ci.org/GoogleChrome/puppeteer) [](https://ci.appveyor.com/project/aslushnikov/puppeteer/branch/master) [](https://npmjs.org/package/puppeteer)
2 |
3 |
4 |
5 | > 此项目同步自 [GoogleChrome](https://github.com/GoogleChrome) / [puppeteer](https://github.com/GoogleChrome/puppeteer) 项目中的 docs.
6 |
7 | ###### [API](#api-文档) | [FAQ](#faq) | [Contributing](#贡献-puppeteer)
8 |
9 | > Puppeteer 是一个 Node 库,它提供了一系列高级 API 来通过 [DevTools 协议](https://chromedevtools.github.io/devtools-protocol/) 控制 [headless](https://developers.google.com/web/updates/2017/04/headless-chrome) Chrome 或 Chromium。 它也可以配置为使用完整的(non-headless)Chrome 或 Chromium。
10 |
11 |
12 | ###### Puppeteer 能做什么?
13 |
14 | 可以在浏览器中手动完成的大部分事情都可以使用 Puppeteer 完成! 你可以通过这里的几个例子来起步:
15 |
16 | * 生成页面的截图和PDF。
17 | * 抓取 SPA 并生成预渲染的内容(即“SSR”)。
18 | * 从网站抓取内容。
19 | * 自动表单提交,UI测试,键盘输入等。
20 | * 创建一个最新的自动化测试环境。 使用最新的 JavaScript 和浏览器功能,直接在最新版本的 Chrome 中运行测试。
21 | * 捕获你网站的 [timeline trace](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/reference),来帮助诊断性能问题。
22 |
23 | 在线尝试: https://try-puppeteer.appspot.com/
24 |
25 | ## 起步
26 |
27 | ### 安装
28 |
29 | > **注意**:Puppeteer 至少需要 Node v6.4.0,而下面的例子中使用的 async/await,只有 Node v7.6.0 或更高版本支持
30 |
31 | 要在你的项目中使用 Puppeteer, 运行:
32 |
33 | ```
34 | yarn add puppeteer
35 | # 或 "npm i puppeteer"
36 | ```
37 |
38 | > **注意**:当你安装 Puppeteer,它会下载最新版本的 Chromium (~71Mb Mac, ~90Mb Linux, ~110Mb Win) 来保证与 API 协同工作。要跳过下载,参考 [Environment variables](docs/api.md#environment-variables)。
39 |
40 | ### 使用
41 |
42 | Puppeteer 对于使用过其他浏览器测试框架的人来说会很熟悉。 你创建一个 `Browser` 实例,打开页面,然后使用 [Puppeteer 的 API](docs/api.md#) 来操作它们。
43 |
44 | **示例** - 导航到 https://example.com 然后保存屏幕截图为 *example.png*:
45 |
46 | ```js
47 | const puppeteer = require('puppeteer');
48 |
49 | (async () => {
50 | const browser = await puppeteer.launch();
51 | const page = await browser.newPage();
52 | await page.goto('https://example.com');
53 | await page.screenshot({path: 'example.png'});
54 |
55 | await browser.close();
56 | })();
57 | ```
58 |
59 | Puppeteer 设定一个初始页面大小为 800px x 600px, 这决定了截图的大小. 页面大小可以用 [`Page.setViewport()`](docs/api.md#pagesetviewportviewport) 来自定义。
60 |
61 | **示例** - 创建一个 PDF.
62 |
63 | ```js
64 | const puppeteer = require('puppeteer');
65 |
66 | (async () => {
67 | const browser = await puppeteer.launch();
68 | const page = await browser.newPage();
69 | await page.goto('https://news.ycombinator.com', {waitUntil: 'networkidle2'});
70 | await page.pdf({path: 'hn.pdf', format: 'A4'});
71 |
72 | await browser.close();
73 | })();
74 | ```
75 |
76 | 参考 [`Page.pdf()`](docs/api.md#pagepdfoptions) 来获取关于 pdf 的更多内容。
77 |
78 | **示例** - 评估页面上下文中的脚本
79 |
80 | ```js
81 | const puppeteer = require('puppeteer');
82 |
83 | (async () => {
84 | const browser = await puppeteer.launch();
85 | const page = await browser.newPage();
86 | await page.goto('https://example.com');
87 |
88 | // Get the "viewport" of the page, as reported by the page.
89 | const dimensions = await page.evaluate(() => {
90 | return {
91 | width: document.documentElement.clientWidth,
92 | height: document.documentElement.clientHeight,
93 | deviceScaleFactor: window.devicePixelRatio
94 | };
95 | });
96 |
97 | console.log('Dimensions:', dimensions);
98 |
99 | await browser.close();
100 | })();
101 | ```
102 |
103 | 请参阅 [`Page.evaluate()`](docs/api.md#pageevaluatepagefunction-args) 以获取更多关于 `evaluate` 和相关方法的信息,如`evaluateOnNewDocument` 和 `exposeFunction`。
104 |
105 | ## 默认运行时设置
106 |
107 | **1. 使用 Headless 模式**
108 |
109 | Puppeteer 在 [headless 模式](https://developers.google.com/web/updates/2017/04/headless-chrome) 中运行 Chromium。要运行完整版本的 Chromium, 需在浏览器加载时设置 ['headless' 参数](docs/api.md#puppeteerlaunchoptions):
110 |
111 | ```js
112 | const browser = await puppeteer.launch({headless: false}); // 默认是 true
113 | ```
114 |
115 | **2. 运行 Chromium 的捆绑版本**
116 |
117 | 默认情况下,Puppeteer 下载并使用特定版本的 Chromium,以便使它的 API 保证能开箱即用。 要让 Puppeteer 使用不同版本的 Chrome 或 Chromium,则当创建一个 `Browser` 实例时传入可执行文件的路径:
118 |
119 | ```js
120 | const browser = await puppeteer.launch({executablePath: '/path/to/Chrome'});
121 | ```
122 |
123 | 参考 [`Puppeteer.launch()`](docs/api.md#puppeteerlaunchoptions) 获取更多信息。
124 |
125 | 参考 [`本文`](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/) 来了解 Chromium 和 Chrome 之间的区别。 [`本文`](https://chromium.googlesource.com/chromium/src/+/lkcr/docs/chromium_browser_vs_google_chrome.md) 将介绍对于 Linux 用户的一些差异.
126 |
127 | **3. 创建一个新的用户配置文件**
128 |
129 | Puppeteer 创建它自己的 Chromium 用户配置文件,并在**每次运行时清理它**。
130 |
131 | ## API 文档
132 |
133 | 浏览 [API 文档](docs/api.md) 和 [示例](https://github.com/GoogleChrome/puppeteer/tree/master/examples/) 来学习更多内容。
134 |
135 | ## 调试提示
136 |
137 | 1. 关闭 headless 模式 - 有时查看浏览器显示的内容是非常有用的,而不是在 headless 模式下启动。使用 `headless:false` 启动完整版本的浏览器:
138 |
139 | ```js
140 | const browser = await puppeteer.launch({headless: false});
141 | ```
142 |
143 | 2. 慢下来 - `slowMo` 参数可是使 Puppeteer 操作速度减少指定的毫秒数。 这是另一种帮助查看发生了什么的方法。
144 |
145 | ```js
146 | const browser = await puppeteer.launch({
147 | headless: false,
148 | slowMo: 250 // 放慢了 250ms
149 | });
150 | ```
151 |
152 | 3. 捕获控制台输出 - 您可以侦听 `console` 事件。在 `page.evaluate()` 中调试代码时,这也很方便:
153 |
154 | ```js
155 | page.on('console', msg => console.log('PAGE LOG:', ...msg.args));
156 |
157 | await page.evaluate(() => console.log(`url is ${location.href}`));
158 | ```
159 |
160 | 4. 启用详细日志记录 - 所有公共 API 调用和内部协议流将通过 `puppeteer` 命名空间下的 [`debug`](https://github.com/visionmedia/debug) 模块进行记录。
161 |
162 | ```sh
163 | # 基本的详细记录
164 | env DEBUG="puppeteer:*" node script.js
165 |
166 | # DEBUG 输出可以通过命名空间来启用/禁用
167 | env DEBUG="puppeteer:*,-puppeteer:protocol" node script.js # 所有协议消息
168 | env DEBUG="puppeteer:session" node script.js # 协议会话消息(协议消息到目标)
169 | env DEBUG="puppeteer:mouse,puppeteer:keyboard" node script.js # 只有鼠标和键盘的 API 调用
170 |
171 | # 协议流可能相当嘈杂。 这个例子过滤掉所有网络域的消息
172 | env DEBUG="puppeteer:*" env DEBUG_COLORS=true node script.js 2>&1 | grep -v '"Network'
173 | ```
174 |
175 | ## 贡献 Puppeteer
176 |
177 | 查看 [贡献指南](https://github.com/GoogleChrome/puppeteer/blob/master/CONTRIBUTING.md) 来获得有关 Puppeteer 开发的概述。
178 |
179 | # FAQ
180 |
181 | #### Q: Puppeteer 使用哪个 Chromium 版本?
182 |
183 | 在 [package.json](https://github.com/GoogleChrome/puppeteer/blob/master/package.json) 中查看 `chromium_revision`.
184 |
185 | Puppeteer 捆绑 Chromium 来确保它使用的最新功能可用。 随着 DevTools 协议和浏览器的不断改进,Puppeteer 将被更新为依赖于更新版本的 Chromium。
186 |
187 | #### Q: Puppeteer,Selenium / WebDriver 和 PhantomJS 有什么区别?
188 |
189 | Selenium / WebDriver是一个完善的跨浏览器API,可用于测试跨浏览器支持。
190 |
191 | Puppeteer 仅适用于 Chromium 或 Chrome。 但是,许多团队只使用一个浏览器(例如PhantomJS)进行单元测试。 在非测试用例中,Puppeteer 提供了一个功能强大但简单的API,因为它只针对一个浏览器,使您能够快速开发自动化脚本。
192 |
193 | Puppeteer 捆绑了最新版本的 Chromium。
194 |
195 | #### Q: 谁维护 Puppeteer?
196 |
197 | Chrome DevTools 团队负责维护该库,然而我们非常乐意在项目中提供帮助和专业知识!
198 | 参考 [Contributing](https://github.com/GoogleChrome/puppeteer/blob/master/CONTRIBUTING.md).
199 |
200 | #### Q: Chrome 团队为什么要打造 Puppeteer?
201 |
202 | 该项目的目标很简单:
203 |
204 | - 提供一个精简的,规范的库,强调 [DevTools 协议](https://chromedevtools.github.io/devtools-protocol/) 的功能。
205 | - 为类似的测试库的实现提供参考。 最终,这些其他框架可以采用 Puppeteer 作为其基础层。
206 | - 越来越多的采用 headless/automated 浏览器测试。
207 | - 帮助养成新的 DevTools 协议功能...并捕捉错误!
208 | - 详细了解自动浏览器测试的难点,并帮助填补这些空白。
209 |
210 | #### Q: Puppeteer 与其他 headless Chrome 项目相比如何?
211 |
212 | 过去几个月,[为自动化 headless Chrome 带来了一些新的库](https://medium.com/@kensoh/chromeless-chrominator-chromy-navalia-lambdium-ghostjs-autogcd-ef34bcd26907)。 作为开发 DevTools 协议的团队,我们很高兴看到和支持这个蓬勃发展的生态系统。
213 |
214 | 我们已经联系了一些这样的项目,看看是否有合作的机会,我们很乐意尽我们所能帮助。
215 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 |
294 | Copyright (C)
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | , 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/docs/api.md:
--------------------------------------------------------------------------------
1 | # Puppeteer API v1.0.0-rc
2 |
3 | ##### 内容目录
4 |
5 |
6 |
7 | - [概览](#overview)
8 | - [环境变量](#environment-variables)
9 | - [class: Puppeteer](#class-puppeteer)
10 | * [puppeteer.connect(options)](#puppeteerconnectoptions)
11 | * [puppeteer.defaultArgs()](#puppeteerdefaultargs)
12 | * [puppeteer.executablePath()](#puppeteerexecutablepath)
13 | * [puppeteer.launch([options])](#puppeteerlaunchoptions)
14 | - [class: Browser](#class-browser)
15 | * [event: 'disconnected'](#event-disconnected)
16 | * [event: 'targetchanged'](#event-targetchanged)
17 | * [event: 'targetcreated'](#event-targetcreated)
18 | * [event: 'targetdestroyed'](#event-targetdestroyed)
19 | * [browser.close()](#browserclose)
20 | * [browser.disconnect()](#browserdisconnect)
21 | * [browser.newPage()](#browsernewpage)
22 | * [browser.pages()](#browserpages)
23 | * [browser.process()](#browserprocess)
24 | * [browser.targets()](#browsertargets)
25 | * [browser.userAgent()](#browseruseragent)
26 | * [browser.version()](#browserversion)
27 | * [browser.wsEndpoint()](#browserwsendpoint)
28 | - [class: Page](#class-page)
29 | * [event: 'console'](#event-console)
30 | * [event: 'dialog'](#event-dialog)
31 | * [event: 'error'](#event-error)
32 | * [event: 'frameattached'](#event-frameattached)
33 | * [event: 'framedetached'](#event-framedetached)
34 | * [event: 'framenavigated'](#event-framenavigated)
35 | * [event: 'load'](#event-load)
36 | * [event: 'metrics'](#event-metrics)
37 | * [event: 'pageerror'](#event-pageerror)
38 | * [event: 'request'](#event-request)
39 | * [event: 'requestfailed'](#event-requestfailed)
40 | * [event: 'requestfinished'](#event-requestfinished)
41 | * [event: 'response'](#event-response)
42 | * [page.$(selector)](#pageselector)
43 | * [page.$$(selector)](#pageselector)
44 | * [page.$$eval(selector, pageFunction[, ...args])](#pageevalselector-pagefunction-args)
45 | * [page.$eval(selector, pageFunction[, ...args])](#pageevalselector-pagefunction-args)
46 | * [page.$x(expression)](#pagexexpression)
47 | * [page.addScriptTag(options)](#pageaddscripttagoptions)
48 | * [page.addStyleTag(options)](#pageaddstyletagoptions)
49 | * [page.authenticate(credentials)](#pageauthenticatecredentials)
50 | * [page.bringToFront()](#pagebringtofront)
51 | * [page.click(selector[, options])](#pageclickselector-options)
52 | * [page.close()](#pageclose)
53 | * [page.content()](#pagecontent)
54 | * [page.cookies(...urls)](#pagecookiesurls)
55 | * [page.coverage](#pagecoverage)
56 | * [page.deleteCookie(...cookies)](#pagedeletecookiecookies)
57 | * [page.emulate(options)](#pageemulateoptions)
58 | * [page.emulateMedia(mediaType)](#pageemulatemediamediatype)
59 | * [page.evaluate(pageFunction, ...args)](#pageevaluatepagefunction-args)
60 | * [page.evaluateHandle(pageFunction, ...args)](#pageevaluatehandlepagefunction-args)
61 | * [page.evaluateOnNewDocument(pageFunction, ...args)](#pageevaluateonnewdocumentpagefunction-args)
62 | * [page.exposeFunction(name, puppeteerFunction)](#pageexposefunctionname-puppeteerfunction)
63 | * [page.focus(selector)](#pagefocusselector)
64 | * [page.frames()](#pageframes)
65 | * [page.goBack(options)](#pagegobackoptions)
66 | * [page.goForward(options)](#pagegoforwardoptions)
67 | * [page.goto(url, options)](#pagegotourl-options)
68 | * [page.hover(selector)](#pagehoverselector)
69 | * [page.keyboard](#pagekeyboard)
70 | * [page.mainFrame()](#pagemainframe)
71 | * [page.metrics()](#pagemetrics)
72 | * [page.mouse](#pagemouse)
73 | * [page.pdf(options)](#pagepdfoptions)
74 | * [page.queryObjects(prototypeHandle)](#pagequeryobjectsprototypehandle)
75 | * [page.reload(options)](#pagereloadoptions)
76 | * [page.screenshot([options])](#pagescreenshotoptions)
77 | * [page.select(selector, ...values)](#pageselectselector-values)
78 | * [page.setContent(html)](#pagesetcontenthtml)
79 | * [page.setCookie(...cookies)](#pagesetcookiecookies)
80 | * [page.setExtraHTTPHeaders(headers)](#pagesetextrahttpheadersheaders)
81 | * [page.setJavaScriptEnabled(enabled)](#pagesetjavascriptenabledenabled)
82 | * [page.setOfflineMode(enabled)](#pagesetofflinemodeenabled)
83 | * [page.setRequestInterception(value)](#pagesetrequestinterceptionvalue)
84 | * [page.setUserAgent(userAgent)](#pagesetuseragentuseragent)
85 | * [page.setViewport(viewport)](#pagesetviewportviewport)
86 | * [page.tap(selector)](#pagetapselector)
87 | * [page.title()](#pagetitle)
88 | * [page.touchscreen](#pagetouchscreen)
89 | * [page.tracing](#pagetracing)
90 | * [page.type(selector, text[, options])](#pagetypeselector-text-options)
91 | * [page.url()](#pageurl)
92 | * [page.viewport()](#pageviewport)
93 | * [page.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])](#pagewaitforselectororfunctionortimeout-options-args)
94 | * [page.waitForFunction(pageFunction[, options[, ...args]])](#pagewaitforfunctionpagefunction-options-args)
95 | * [page.waitForNavigation(options)](#pagewaitfornavigationoptions)
96 | * [page.waitForSelector(selector[, options])](#pagewaitforselectorselector-options)
97 | - [class: Keyboard](#class-keyboard)
98 | * [keyboard.down(key[, options])](#keyboarddownkey-options)
99 | * [keyboard.press(key[, options])](#keyboardpresskey-options)
100 | * [keyboard.sendCharacter(char)](#keyboardsendcharacterchar)
101 | * [keyboard.type(text, options)](#keyboardtypetext-options)
102 | * [keyboard.up(key)](#keyboardupkey)
103 | - [class: Mouse](#class-mouse)
104 | * [mouse.click(x, y, [options])](#mouseclickx-y-options)
105 | * [mouse.down([options])](#mousedownoptions)
106 | * [mouse.move(x, y, [options])](#mousemovex-y-options)
107 | * [mouse.up([options])](#mouseupoptions)
108 | - [class: Touchscreen](#class-touchscreen)
109 | * [touchscreen.tap(x, y)](#touchscreentapx-y)
110 | - [class: Tracing](#class-tracing)
111 | * [tracing.start(options)](#tracingstartoptions)
112 | * [tracing.stop()](#tracingstop)
113 | - [class: Dialog](#class-dialog)
114 | * [dialog.accept([promptText])](#dialogacceptprompttext)
115 | * [dialog.defaultValue()](#dialogdefaultvalue)
116 | * [dialog.dismiss()](#dialogdismiss)
117 | * [dialog.message()](#dialogmessage)
118 | * [dialog.type()](#dialogtype)
119 | - [class: ConsoleMessage](#class-consolemessage)
120 | * [consoleMessage.args()](#consolemessageargs)
121 | * [consoleMessage.text()](#consolemessagetext)
122 | * [consoleMessage.type()](#consolemessagetype)
123 | - [class: Frame](#class-frame)
124 | * [frame.$(selector)](#frameselector)
125 | * [frame.$$(selector)](#frameselector)
126 | * [frame.$$eval(selector, pageFunction[, ...args])](#frameevalselector-pagefunction-args)
127 | * [frame.$eval(selector, pageFunction[, ...args])](#frameevalselector-pagefunction-args)
128 | * [frame.$x(expression)](#framexexpression)
129 | * [frame.addScriptTag(options)](#frameaddscripttagoptions)
130 | * [frame.addStyleTag(options)](#frameaddstyletagoptions)
131 | * [frame.childFrames()](#framechildframes)
132 | * [frame.content()](#framecontent)
133 | * [frame.evaluate(pageFunction, ...args)](#frameevaluatepagefunction-args)
134 | * [frame.executionContext()](#frameexecutioncontext)
135 | * [frame.isDetached()](#frameisdetached)
136 | * [frame.name()](#framename)
137 | * [frame.parentFrame()](#frameparentframe)
138 | * [frame.select(selector, ...values)](#frameselectselector-values)
139 | * [frame.setContent(html)](#framesetcontenthtml)
140 | * [frame.title()](#frametitle)
141 | * [frame.url()](#frameurl)
142 | * [frame.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])](#framewaitforselectororfunctionortimeout-options-args)
143 | * [frame.waitForFunction(pageFunction[, options[, ...args]])](#framewaitforfunctionpagefunction-options-args)
144 | * [frame.waitForSelector(selector[, options])](#framewaitforselectorselector-options)
145 | - [class: ExecutionContext](#class-executioncontext)
146 | * [executionContext.evaluate(pageFunction, ...args)](#executioncontextevaluatepagefunction-args)
147 | * [executionContext.evaluateHandle(pageFunction, ...args)](#executioncontextevaluatehandlepagefunction-args)
148 | * [executionContext.queryObjects(prototypeHandle)](#executioncontextqueryobjectsprototypehandle)
149 | - [class: JSHandle](#class-jshandle)
150 | * [jsHandle.asElement()](#jshandleaselement)
151 | * [jsHandle.dispose()](#jshandledispose)
152 | * [jsHandle.executionContext()](#jshandleexecutioncontext)
153 | * [jsHandle.getProperties()](#jshandlegetproperties)
154 | * [jsHandle.getProperty(propertyName)](#jshandlegetpropertypropertyname)
155 | * [jsHandle.jsonValue()](#jshandlejsonvalue)
156 | - [class: ElementHandle](#class-elementhandle)
157 | * [elementHandle.$(selector)](#elementhandleselector)
158 | * [elementHandle.$$(selector)](#elementhandleselector)
159 | * [elementHandle.$x(expression)](#elementhandlexexpression)
160 | * [elementHandle.asElement()](#elementhandleaselement)
161 | * [elementHandle.boundingBox()](#elementhandleboundingbox)
162 | * [elementHandle.click([options])](#elementhandleclickoptions)
163 | * [elementHandle.dispose()](#elementhandledispose)
164 | * [elementHandle.executionContext()](#elementhandleexecutioncontext)
165 | * [elementHandle.focus()](#elementhandlefocus)
166 | * [elementHandle.getProperties()](#elementhandlegetproperties)
167 | * [elementHandle.getProperty(propertyName)](#elementhandlegetpropertypropertyname)
168 | * [elementHandle.hover()](#elementhandlehover)
169 | * [elementHandle.jsonValue()](#elementhandlejsonvalue)
170 | * [elementHandle.press(key[, options])](#elementhandlepresskey-options)
171 | * [elementHandle.screenshot([options])](#elementhandlescreenshotoptions)
172 | * [elementHandle.tap()](#elementhandletap)
173 | * [elementHandle.toString()](#elementhandletostring)
174 | * [elementHandle.type(text[, options])](#elementhandletypetext-options)
175 | * [elementHandle.uploadFile(...filePaths)](#elementhandleuploadfilefilepaths)
176 | - [class: Request](#class-request)
177 | * [request.abort([errorCode])](#requestaborterrorcode)
178 | * [request.continue([overrides])](#requestcontinueoverrides)
179 | * [request.failure()](#requestfailure)
180 | * [request.headers()](#requestheaders)
181 | * [request.method()](#requestmethod)
182 | * [request.postData()](#requestpostdata)
183 | * [request.resourceType()](#requestresourcetype)
184 | * [request.respond(response)](#requestrespondresponse)
185 | * [request.response()](#requestresponse)
186 | * [request.url()](#requesturl)
187 | - [class: Response](#class-response)
188 | * [response.buffer()](#responsebuffer)
189 | * [response.headers()](#responseheaders)
190 | * [response.json()](#responsejson)
191 | * [response.ok()](#responseok)
192 | * [response.request()](#responserequest)
193 | * [response.status()](#responsestatus)
194 | * [response.text()](#responsetext)
195 | * [response.url()](#responseurl)
196 | - [class: Target](#class-target)
197 | * [target.page()](#targetpage)
198 | * [target.type()](#targettype)
199 | * [target.url()](#targeturl)
200 | - [class: Coverage](#class-coverage)
201 | * [coverage.startCSSCoverage(options)](#coveragestartcsscoverageoptions)
202 | * [coverage.startJSCoverage(options)](#coveragestartjscoverageoptions)
203 | * [coverage.stopCSSCoverage()](#coveragestopcsscoverage)
204 | * [coverage.stopJSCoverage()](#coveragestopjscoverage)
205 |
206 |
207 |
208 | ### 概览
209 |
210 | Puppeteer 是一个 Node 库,它提供了一系列高级 API 来使用 DevTools协议 控制 Chromium 或者 Chrome。
211 |
212 | Puppeteer API 是分层并且镜像于浏览器的结构。在下面的图表上,褪色的实体当前没有在Puppeteer 中表现出来。
213 |
214 | 
215 |
216 | - [`Puppeteer`](#class-puppeteer) 使用 [devtools 协议](https://chromedevtools.github.io/devtools-protocol/) 与浏览器通信。
217 | - [`Browser`](#class-browser) 实例拥有多个页面。
218 | - [`Page`](#class-page) 至少有一个框架: 主框架。 可能还有其他由 [iframe](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) 或 [frame](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/frame) 标签创建的框架。
219 | - [`Frame`](#class-frame) 至少有一个可执行上下文 - 默认可执行上下文 - 其中框架的 JavaScript 被执行。框架可能有额外的与[扩展](https://developer.chrome.com/extensions)相关联的执行上下文。
220 |
221 | (图表资源: [link](https://docs.google.com/drawings/d/1Q_AM6KYs9kbyLZF-Lpp5mtpAWth73Cq8IKCsWYgi8MM/edit?usp=sharing))
222 |
223 |
224 | ### 环境变量
225 |
226 | Puppeteer 会查找某些 [环境变量](https://en.wikipedia.org/wiki/Environment_variable) 来帮助其操作。 这些变量既可以在环境中设置,也可以在 [npm 配置](https://docs.npmjs.com/cli/config) 中设置。
227 |
228 | - `HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY` - 定义用于下载和运行 Chromium 的 HTTP 代理设置。
229 | - `PUPPETEER_SKIP_CHROMIUM_DOWNLOAD` - 安装过程中不要下载捆绑的 Chromium。
230 | - `PUPPETEER_DOWNLOAD_HOST` - 覆盖用于下载 Chromium 的 URL 的主机部分
231 |
232 | ### class: Puppeteer
233 |
234 | Puppeteer module provides a method to launch a Chromium instance.
235 | The following is a typical example of using a Puppeteer to drive automation:
236 | ```js
237 | const puppeteer = require('puppeteer');
238 |
239 | puppeteer.launch().then(async browser => {
240 | const page = await browser.newPage();
241 | await page.goto('https://www.google.com');
242 | // other actions...
243 | await browser.close();
244 | });
245 | ```
246 |
247 | #### puppeteer.connect(options)
248 | - `options` <[Object]>
249 | - `browserWSEndpoint` <[string]> a [browser websocket endpoint](#browserwsendpoint) to connect to.
250 | - `ignoreHTTPSErrors` <[boolean]> Whether to ignore HTTPS errors during navigation. Defaults to `false`.
251 | - returns: <[Promise]<[Browser]>>
252 |
253 | This methods attaches Puppeteer to an existing Chromium instance.
254 |
255 | #### puppeteer.defaultArgs()
256 | - returns: <[Array]<[string]>> The default flags that Chromium will be launched with.
257 |
258 | #### puppeteer.executablePath()
259 | - returns: <[string]> A path where Puppeteer expects to find bundled Chromium. Chromium might not exist there if the download was skipped with [`PUPPETEER_SKIP_CHROMIUM_DOWNLOAD`](#environment-variables).
260 |
261 | #### puppeteer.launch([options])
262 | - `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields:
263 | - `ignoreHTTPSErrors` <[boolean]> Whether to ignore HTTPS errors during navigation. Defaults to `false`.
264 | - `headless` <[boolean]> Whether to run browser in [headless mode](https://developers.google.com/web/updates/2017/04/headless-chrome). Defaults to `true` unless the `devtools` option is `true`.
265 | - `executablePath` <[string]> Path to a Chromium or Chrome executable to run instead of bundled Chromium. If `executablePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
266 | - `slowMo` <[number]> Slows down Puppeteer operations by the specified amount of milliseconds. Useful so that you can see what is going on.
267 | - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. List of Chromium flags can be found [here](http://peter.sh/experiments/chromium-command-line-switches/).
268 | - `ignoreDefaultArgs` <[boolean]> Do not use [`puppeteer.defaultArgs()`](#puppeteerdefaultargs). Dangerous option; use with care. Defaults to `false`.
269 | - `handleSIGINT` <[boolean]> Close browser process on Ctrl-C. Defaults to `true`.
270 | - `handleSIGTERM` <[boolean]> Close browser process on SIGTERM. Defaults to `true`.
271 | - `handleSIGHUP` <[boolean]> Close browser process on SIGHUP. Defaults to `true`.
272 | - `timeout` <[number]> Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.
273 | - `dumpio` <[boolean]> Whether to pipe browser process stdout and stderr into `process.stdout` and `process.stderr`. Defaults to `false`.
274 | - `userDataDir` <[string]> Path to a [User Data Directory](https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md).
275 | - `env` <[Object]> Specify environment variables that will be visible to browser. Defaults to `process.env`.
276 | - `devtools` <[boolean]> Whether to auto-open DevTools panel for each tab. If this option is `true`, the `headless` option will be set `false`.
277 | - returns: <[Promise]<[Browser]>> Promise which resolves to browser instance.
278 |
279 | The method launches a browser instance with given arguments. The browser will be closed when the parent node.js process is closed.
280 |
281 | > **NOTE** Puppeteer can also be used to control the Chrome browser, but it works best with the version of Chromium it is bundled with. There is no
282 | guarantee it will work with any other version. Use `executablePath` option with extreme caution.
283 | If Google Chrome (rather than Chromium) is preferred, a [Chrome Canary](https://www.google.com/chrome/browser/canary.html) or [Dev Channel](https://www.chromium.org/getting-involved/dev-channel) build is suggested.
284 | >
285 | > In [puppeteer.launch([options])](#puppeteerlaunchoptions) above, any mention of Chromium also applies to Chrome.
286 | >
287 | > See [`this article`](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/) for a description
288 | of the differences between Chromium and Chrome. [`This article`](https://chromium.googlesource.com/chromium/src/+/lkcr/docs/chromium_browser_vs_google_chrome.md) describes some differences for Linux users.
289 |
290 | ### class: Browser
291 |
292 | * extends: [`EventEmitter`](https://nodejs.org/api/events.html#events_class_eventemitter)
293 |
294 | A Browser is created when Puppeteer connects to a Chromium instance, either through [`puppeteer.launch`](#puppeteerlaunchoptions) or [`puppeteer.connect`](#puppeteerconnectoptions).
295 |
296 | An example of using a [Browser] to create a [Page]:
297 | ```js
298 | const puppeteer = require('puppeteer');
299 |
300 | puppeteer.launch().then(async browser => {
301 | const page = await browser.newPage();
302 | await page.goto('https://example.com');
303 | await browser.close();
304 | });
305 | ```
306 |
307 | An example of disconnecting from and reconnecting to a [Browser]:
308 | ```js
309 | const puppeteer = require('puppeteer');
310 |
311 | puppeteer.launch().then(async browser => {
312 | // Store the endpoint to be able to reconnect to Chromium
313 | const browserWSEndpoint = browser.wsEndpoint();
314 | // Disconnect puppeteer from Chromium
315 | browser.disconnect();
316 |
317 | // Use the endpoint to reestablish a connection
318 | const browser2 = await puppeteer.connect({browserWSEndpoint});
319 | // Close Chromium
320 | await browser2.close();
321 | });
322 | ```
323 | #### event: 'disconnected'
324 | Emitted when puppeteer gets disconnected from the Chromium instance. This might happen because one of the following:
325 | - Chromium is closed or crashed
326 | - `browser.disconnect` method was called
327 |
328 | #### event: 'targetchanged'
329 | - <[Target]>
330 |
331 | Emitted when the url of a target changes.
332 |
333 | #### event: 'targetcreated'
334 | - <[Target]>
335 |
336 | Emitted when a target is created, for example when a new page is opened by [`window.open`](https://developer.mozilla.org/en-US/docs/Web/API/Window/open) or [`browser.newPage`](#browsernewpage).
337 |
338 | #### event: 'targetdestroyed'
339 | - <[Target]>
340 |
341 | Emitted when a target is destroyed, for example when a page is closed.
342 |
343 | #### browser.close()
344 | - returns: <[Promise]>
345 |
346 | Closes Chromium and all of its pages (if any were opened). The browser object itself is considered disposed and cannot be used anymore.
347 |
348 | #### browser.disconnect()
349 |
350 | Disconnects Puppeteer from the browser, but leaves the Chromium process running. After calling `disconnect`, the browser object is considered disposed and cannot be used anymore.
351 |
352 | #### browser.newPage()
353 | - returns: <[Promise]<[Page]>> Promise which resolves to a new [Page] object.
354 |
355 | #### browser.pages()
356 | - returns: <[Promise]<[Array]<[Page]>>> Promise which resolves to an array of all open pages.
357 |
358 | #### browser.process()
359 | - returns: [ChildProcess]> Spawned browser process. Returns `null` if the browser instance was created with `puppeteer.connect` method.
360 |
361 | #### browser.targets()
362 | - returns: <[Array]<[Target]>> An array of all active targets.
363 |
364 | #### browser.userAgent()
365 | - returns: <[Promise]<[string]>> Promise which resolves to the browser's original user agent.
366 |
367 | > **NOTE** Pages can override browser user agent with [page.setUserAgent](#pagesetuseragentuseragent)
368 |
369 | #### browser.version()
370 | - returns: <[Promise]<[string]>> For headless Chromium, this is similar to `HeadlessChrome/61.0.3153.0`. For non-headless, this is similar to `Chrome/61.0.3153.0`.
371 |
372 | > **NOTE** the format of browser.version() might change with future releases of Chromium.
373 |
374 | #### browser.wsEndpoint()
375 | - returns: <[string]> Browser websocket url.
376 |
377 | Browser websocket endpoint which can be used as an argument to
378 | [puppeteer.connect](#puppeteerconnectoptions). The format is `ws://${host}:${port}/devtools/browser/`
379 |
380 | You can find the `webSocketDebuggerUrl` from `http://${host}:${port}/json/version`. Learn more about the [devtools protocol](https://chromedevtools.github.io/devtools-protocol) and the [browser endpoint](https://chromedevtools.github.io/devtools-protocol/#how-do-i-access-the-browser-target).
381 |
382 | ### class: Page
383 |
384 | * extends: [`EventEmitter`](https://nodejs.org/api/events.html#events_class_eventemitter)
385 |
386 | Page provides methods to interact with a single tab in Chromium. One [Browser] instance might have multiple [Page] instances.
387 |
388 | This example creates a page, navigates it to a URL, and then saves a screenshot:
389 | ```js
390 | const puppeteer = require('puppeteer');
391 |
392 | puppeteer.launch().then(async browser => {
393 | const page = await browser.newPage();
394 | await page.goto('https://example.com');
395 | await page.screenshot({path: 'screenshot.png'});
396 | await browser.close();
397 | });
398 | ```
399 |
400 | The Page class emits various events (described below) which can be handled using any of Node's native EventEmitter methods, such as `on` or `once`.
401 |
402 | This example logs a message for a single page `load` event:
403 | ```js
404 | page.once('load', () => console.log('Page loaded!'));
405 | ```
406 |
407 | #### event: 'console'
408 | - <[ConsoleMessage]>
409 |
410 | Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also emitted if the page throws an error or a warning.
411 |
412 | The arguments passed into `console.log` appear as arguments on the event handler.
413 |
414 | An example of handling `console` event:
415 | ```js
416 | page.on('console', msg => {
417 | for (let i = 0; i < msg.args.length; ++i)
418 | console.log(`${i}: ${msg.args[i]}`);
419 | });
420 | page.evaluate(() => console.log('hello', 5, {foo: 'bar'}));
421 | ```
422 |
423 | #### event: 'dialog'
424 | - <[Dialog]>
425 |
426 | Emitted when a JavaScript dialog appears, such as `alert`, `prompt`, `confirm` or `beforeunload`. Puppeteer can respond to the dialog via [Dialog]'s [accept](#dialogacceptprompttext) or [dismiss](#dialogdismiss) methods.
427 |
428 | #### event: 'error'
429 | - <[Error]>
430 |
431 | Emitted when the page crashes.
432 |
433 | > **NOTE** `error` event has a special meaning in Node, see [error events](https://nodejs.org/api/events.html#events_error_events) for details.
434 |
435 | #### event: 'frameattached'
436 | - <[Frame]>
437 |
438 | Emitted when a frame is attached.
439 |
440 | #### event: 'framedetached'
441 | - <[Frame]>
442 |
443 | Emitted when a frame is detached.
444 |
445 | #### event: 'framenavigated'
446 | - <[Frame]>
447 |
448 | Emitted when a frame is navigated to a new url.
449 |
450 | #### event: 'load'
451 |
452 | Emitted when the JavaScript [`load`](https://developer.mozilla.org/en-US/docs/Web/Events/load) event is dispatched.
453 |
454 | #### event: 'metrics'
455 | - <[Object]>
456 | - `title` <[string]> The title passed to `console.timeStamp`.
457 | - `metrics` <[Object]> Object containing metrics as key/value pairs. The values
458 | of metrics are of <[number]> type.
459 |
460 | Emitted when the JavaScript code makes a call to `console.timeStamp`. For the list
461 | of metrics see `page.metrics`.
462 |
463 | #### event: 'pageerror'
464 | - <[string]> The exception message
465 |
466 | Emitted when an uncaught exception happens within the page.
467 |
468 | #### event: 'request'
469 | - <[Request]>
470 |
471 | Emitted when a page issues a request. The [request] object is read-only.
472 | In order to intercept and mutate requests, see `page.setRequestInterception`.
473 |
474 | #### event: 'requestfailed'
475 | - <[Request]>
476 |
477 | Emitted when a request fails, for example by timing out.
478 |
479 | #### event: 'requestfinished'
480 | - <[Request]>
481 |
482 | Emitted when a request finishes successfully.
483 |
484 | #### event: 'response'
485 | - <[Response]>
486 |
487 | Emitted when a [response] is received.
488 |
489 | #### page.$(selector)
490 | - `selector` <[string]> A [selector] to query page for
491 | - returns: <[Promise][ElementHandle]>>
492 |
493 | The method runs `document.querySelector` within the page. If no element matches the selector, the return value resolve to `null`.
494 |
495 | Shortcut for [page.mainFrame().$(selector)](#frameselector).
496 |
497 | #### page.$$(selector)
498 | - `selector` <[string]> A [selector] to query page for
499 | - returns: <[Promise]<[Array]<[ElementHandle]>>>
500 |
501 | The method runs `document.querySelectorAll` within the page. If no elements match the selector, the return value resolve to `[]`.
502 |
503 | Shortcut for [page.mainFrame().$$(selector)](#frameselector-1).
504 |
505 |
506 | #### page.$$eval(selector, pageFunction[, ...args])
507 | - `selector` <[string]> A [selector] to query frame for
508 | - `pageFunction` <[function]> Function to be evaluated in browser context
509 | - `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction`
510 | - returns: <[Promise]<[Serializable]>> Promise which resolves to the return value of `pageFunction`
511 |
512 | This method runs `document.querySelectorAll` within the page and passes it as the first argument to `pageFunction`.
513 |
514 | If `pageFunction` returns a [Promise], then `page.$$eval` would wait for the promise to resolve and return its value.
515 |
516 | Examples:
517 | ```js
518 | const divsCounts = await page.$$eval('div', divs => divs.length);
519 | ```
520 |
521 | #### page.$eval(selector, pageFunction[, ...args])
522 | - `selector` <[string]> A [selector] to query page for
523 | - `pageFunction` <[function]> Function to be evaluated in browser context
524 | - `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction`
525 | - returns: <[Promise]<[Serializable]>> Promise which resolves to the return value of `pageFunction`
526 |
527 | This method runs `document.querySelector` within the page and passes it as the first argument to `pageFunction`. If there's no element matching `selector`, the method throws an error.
528 |
529 | If `pageFunction` returns a [Promise], then `page.$eval` would wait for the promise to resolve and return its value.
530 |
531 | Examples:
532 | ```js
533 | const searchValue = await page.$eval('#search', el => el.value);
534 | const preloadHref = await page.$eval('link[rel=preload]', el => el.href);
535 | const html = await page.$eval('.main-container', e => e.outerHTML);
536 | ```
537 |
538 | Shortcut for [page.mainFrame().$eval(selector, pageFunction)](#frameevalselector-pagefunction-args).
539 |
540 | #### page.$x(expression)
541 | - `expression` <[string]> Expression to [evaluate](https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate).
542 | - returns: <[Promise]<[Array]<[ElementHandle]>>>
543 |
544 | The method evluates the XPath expression.
545 |
546 | Shortcut for [page.mainFrame().$x(expression)](#frameexpression)
547 |
548 | #### page.addScriptTag(options)
549 | - `options` <[Object]>
550 | - `url` <[string]> Url of a script to be added.
551 | - `path` <[string]> Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
552 | - `content` <[string]> Raw JavaScript content to be injected into frame.
553 | - returns: <[Promise]<[ElementHandle]>> which resolves to the added tag when the script's onload fires or when the script content was injected into frame.
554 |
555 | Adds a `