Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /tools /auto-nav.py
blob: f056d5e3fdcec3466e9d7b0f2e3c0076f5c20d32 [file] [log] [blame]
Avi Drissmandfd880852022-09-15 20:11:09[diff] [blame]1# Copyright 2020 The Chromium Authors
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4"""
5This script runs Chrome and automatically navigates through the given list of
6URLs the specified number of times.
7
Jesse McKennacb760eaa2021-05-13 22:17:45[diff] [blame]8Usage: vpython3 auto-nav.py <chrome dir> <number of navigations> <url> <url> ...
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]9
10Optional flags:
11* --interval <seconds>, -i <seconds>: specify a number of seconds to wait
12 between navigations, e.g., -i=5
Jesse McKenna599aa522021-02-23 02:05:38[diff] [blame]13* --start_prompt, -s: start Chrome, then wait for the user to press Enter before
14 starting auto-navigation
15* --exit-prompt, -e: after auto-navigation, wait for the user to press Enter
16 before shutting down chrome.exe
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]17* --idlewakeups_dir: Windows only; specify the directory containing
18 idlewakeups.exe to print measurements taken by IdleWakeups,
19 e.g., --idlewakeups_dir=tools/win/IdleWakeups/x64/Debug
Jesse McKenna6e210602020-10-29 22:42:48[diff] [blame]20
21Optional flags to chrome.exe, example:
22-- --user-data-dir=temp --disable-features=SomeFeature
23Note: must be at end of command, following options terminator "--". The options
24terminator stops command-line options from being interpreted as options for this
25script, which would cause an unrecognized-argument error.
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]26"""
27
28# [VPYTHON:BEGIN]
Jesse McKennacb760eaa2021-05-13 22:17:45[diff] [blame]29# python_version: "3.8"
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]30# wheel: <
31# name: "infra/python/wheels/selenium-py2_py3"
32# version: "version:3.14.0"
33# >
34# wheel: <
35# name: "infra/python/wheels/urllib3-py2_py3"
36# version: "version:1.24.3"
37# >
38# wheel: <
39# name: "infra/python/wheels/psutil/${vpython_platform}"
Jesse McKennacb760eaa2021-05-13 22:17:45[diff] [blame]40# version: "version:5.7.2"
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]41# >
42# [VPYTHON:END]
43
44import argparse
45import os
46import subprocess
47import sys
48import time
Jesse McKenna1324fe652021-05-13 23:05:20[diff] [blame]49import urllib
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]50
51try:
52import psutil
53from seleniumimport webdriver
54exceptImportError:
Jesse McKenna2a8c00b2022-03-17 20:25:05[diff] [blame]55print('Error importing required modules. Run with vpython3 instead of '
56'python.')
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]57 sys.exit(1)
58
59DEFAULT_INTERVAL=1
Jesse McKenna1324fe652021-05-13 23:05:20[diff] [blame]60EXIT_CODE_ERROR=1
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]61
Jesse McKenna6e210602020-10-29 22:42:48[diff] [blame]62# Splits list |positional_args| into two lists: |urls| and |chrome_args|, where
63# arguments starting with '-' are treated as chrome args, and the rest as URLs.
64defParsePositionalArgs(positional_args):
65 urls, chrome_args=[],[]
66for argin positional_args:
67if arg.startswith('-'):
68 chrome_args.append(arg)
69else:
70 urls.append(arg)
71return[urls, chrome_args]
72
73
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]74# Returns an object containing the arguments parsed from this script's command
75# line.
76defParseArgs():
Jesse McKenna6e210602020-10-29 22:42:48[diff] [blame]77# Customize usage and help to include options to be passed to chrome.exe.
Jesse McKenna2a8c00b2022-03-17 20:25:05[diff] [blame]78 usage_text='''%(prog)s [-h] [--interval INTERVAL] [--start_prompt]
79 [--exit_prompt] [--idlewakeups_dir IDLEWAKEUPS_DIR]
Jesse McKenna6e210602020-10-29 22:42:48[diff] [blame]80 chrome_dir num_navigations url [url ...]
81 [-- --chrome_option ...]'''
82 additional_help_text='''optional arguments to chrome.exe, example:
83 -- --enable-features=MyFeature --browser-startup-dialog
84 Must be at end of command, following the options
85 terminator "--"'''
86 parser= argparse.ArgumentParser(
87 epilog=additional_help_text,
88 usage=usage_text,
89 formatter_class=argparse.RawDescriptionHelpFormatter)
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]90 parser.add_argument(
91'chrome_dir', help='Directory containing chrome.exe and chromedriver.exe')
92 parser.add_argument('num_navigations',
93 type=int,
94 help='Number of times to navigate through list of URLs')
95 parser.add_argument('--interval',
96'-i',
97 type=int,
98 help='Seconds to wait between navigations; default is 1')
Jesse McKenna599aa522021-02-23 02:05:38[diff] [blame]99 parser.add_argument('--start_prompt',
100'-s',
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]101 action='store_true',
Jesse McKenna599aa522021-02-23 02:05:38[diff] [blame]102 help='Wait for confirmation before starting navigation')
103 parser.add_argument('--exit_prompt',
104'-e',
105 action='store_true',
106 help='Wait for confirmation before exiting chrome.exe')
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]107 parser.add_argument(
108'--idlewakeups_dir',
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]109 help='Windows only; directory containing idlewakeups.exe, if using')
110 parser.add_argument(
111'url',
112 nargs='+',
113 help='URL(s) to navigate, separated by spaces; must include scheme, '
114'e.g., "https://"')
Jesse McKenna6e210602020-10-29 22:42:48[diff] [blame]115 args= parser.parse_args()
116 args.url, chrome_args=ParsePositionalArgs(args.url)
117ifnot args.url:
118 parser.print_usage()
119print(os.path.basename(__file__)+': error: missing URL argument')
Jesse McKenna1324fe652021-05-13 23:05:20[diff] [blame]120 exit(EXIT_CODE_ERROR)
121for urlin args.url:
122ifnot urllib.parse.urlparse(url).scheme:
123print(os.path.basename(__file__)+
124': error: URL is missing required scheme (e.g., "https://"): '+ url)
125 exit(EXIT_CODE_ERROR)
Jesse McKenna6e210602020-10-29 22:42:48[diff] [blame]126return[args, chrome_args]
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]127
128
129# If |path| does not exist, prints a generic error plus optional |error_message|
130# and exits.
131defExitIfNotFound(path, error_message=None):
132ifnot os.path.exists(path):
133print('File not found: {}.'.format(path))
134if error_message:
135print(error_message)
Jesse McKenna1324fe652021-05-13 23:05:20[diff] [blame]136 exit(EXIT_CODE_ERROR)
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]137
138
139def main():
140# Parse arguments and check that file paths received are valid.
Jesse McKenna6e210602020-10-29 22:42:48[diff] [blame]141 args, chrome_args=ParseArgs()
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]142ExitIfNotFound(os.path.join(args.chrome_dir,'chrome.exe'),
143'Build target "chrome" to generate it first.')
144 chromedriver_exe= os.path.join(args.chrome_dir,'chromedriver.exe')
145ExitIfNotFound(chromedriver_exe,
146'Build target "chromedriver" to generate it first.')
147if args.idlewakeups_dir:
148 idlewakeups_exe= os.path.join(args.idlewakeups_dir,'idlewakeups.exe')
149ExitIfNotFound(idlewakeups_exe)
150
151# Start chrome.exe. Disable chrome.exe's extensive logging to make reading
152# this script's output easier.
153 chrome_options= webdriver.ChromeOptions()
154 chrome_options.add_experimental_option('excludeSwitches',['enable-logging'])
Jesse McKenna6e210602020-10-29 22:42:48[diff] [blame]155for argin chrome_args:
156 chrome_options.add_argument(arg)
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]157 driver= webdriver.Chrome(os.path.abspath(chromedriver_exe),
158 options=chrome_options)
159
Jesse McKenna599aa522021-02-23 02:05:38[diff] [blame]160if args.start_prompt:
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]161 driver.get(args.url[0])
Jesse McKennacb760eaa2021-05-13 22:17:45[diff] [blame]162 input('Press Enter to begin navigation...')
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]163
164# Start IdleWakeups, if using, passing the browser process's ID as its target.
165# IdleWakeups will monitor the browser process and its children. Other running
166# chrome.exe processes (i.e., those not launched by this script) are excluded.
167if args.idlewakeups_dir:
168 launched_processes= psutil.Process(
169 driver.service.process.pid).children(recursive=False)
170ifnot launched_processes:
171print('Error getting browser process ID for IdleWakeups.')
172 exit()
173# Assume the first child process created by |driver| is the browser process.
174 idlewakeups= subprocess.Popen([
175 idlewakeups_exe,
176 str(launched_processes[0].pid),'--stop-on-exit','--tabbed'
177],
178 stdout=subprocess.PIPE)
179
180# Navigate through |args.url| list |args.num_navigations| times, then close
181# chrome.exe.
182 interval= args.intervalif args.intervalelse DEFAULT_INTERVAL
183for _in range(args.num_navigations):
184for urlin args.url:
185 driver.get(url)
186 time.sleep(interval)
Jesse McKenna599aa522021-02-23 02:05:38[diff] [blame]187
188if args.exit_prompt:
Jesse McKennacb760eaa2021-05-13 22:17:45[diff] [blame]189 input('Press Enter to exit...')
Jesse McKenna5ab05eb2020-10-23 20:32:30[diff] [blame]190 driver.quit()
191
192# Print IdleWakeups' output, if using.
193if args.idlewakeups_dir:
194print(idlewakeups.communicate()[0])
195
196
197if __name__=='__main__':
198 sys.exit(main())

[8]ページ先頭

©2009-2025 Movatter.jp