Skip to content

Commit

Permalink
v2.94
Browse files Browse the repository at this point in the history
  • Loading branch information
maaaaz committed Aug 23, 2020
1 parent defc86b commit 16e5c2a
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 14 deletions.
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ domain_or_ip(/resource)

### Options
```
webscreenshot.py version 2.93
webscreenshot.py version 2.94
usage: webscreenshot.py [-h] [-i INPUT_FILE] [-o OUTPUT_DIRECTORY] [-w WORKERS] [-v] [--no-error-file] [-p PORT] [-s] [-m]
usage: webscreenshot.py [-h] [-i INPUT_FILE] [-o OUTPUT_DIRECTORY] [-w WORKERS] [-v] [--no-error-file] [-z SINGLE_OUTPUT_FILE] [-p PORT] [-s] [-m]
[-r {phantomjs,chrome,chromium,edgechromium,firefox}] [--renderer-binary RENDERER_BINARY] [--no-xserver] [--window-size WINDOW_SIZE]
[-f {pdf,png,jpg,jpeg,bmp,ppm}] [-q [0-100]] [--ajax-max-timeouts AJAX_MAX_TIMEOUTS] [--crop CROP] [-l] [--label-size LABEL_SIZE]
[--label-bg-color LABEL_BG_COLOR] [--imagemagick-binary IMAGEMAGICK_BINARY] [-c COOKIE] [-a HEADER] [-u HTTP_USERNAME]
[-b HTTP_PASSWORD] [-P PROXY] [-A PROXY_AUTH] [-T PROXY_TYPE] [-t TIMEOUT]
[-f {pdf,png,jpg,jpeg,bmp,ppm}] [-q [0-100]] [--ajax-max-timeouts AJAX_MAX_TIMEOUTS] [--crop CROP] [--custom-js CUSTOM_JS] [-l]
[--label-size LABEL_SIZE] [--label-bg-color LABEL_BG_COLOR] [--imagemagick-binary IMAGEMAGICK_BINARY] [-c COOKIE] [-a HEADER]
[-u HTTP_USERNAME] [-b HTTP_PASSWORD] [-P PROXY] [-A PROXY_AUTH] [-T PROXY_TYPE] [-t TIMEOUT]
[URL]
optional arguments:
Expand All @@ -58,6 +58,8 @@ Main parameters:
<WORKERS> (optional): number of parallel execution workers (default 4)
-v, --verbosity <VERBOSITY> (optional): verbosity level, repeat it to increase the level { -v INFO, -vv DEBUG } (default verbosity ERROR)
--no-error-file <NO_ERROR_FILE> (optional): do not write a file with the list of URL of failed screenshots (default false)
-z SINGLE_OUTPUT_FILE, --single-output-file SINGLE_OUTPUT_FILE
<SINGLE_OUTPUT_FILE> (optional): name of a file which will be the single output of all inputs. Ex. test.png
Input processing parameters:
-p PORT, --port PORT <PORT> (optional): use the specified port for each target in the input list. Ex: -p 80
Expand Down Expand Up @@ -85,6 +87,9 @@ Screenshot image parameters:
<AJAX_MAX_TIMEOUTS> (optional, phantomjs only): per AJAX request, and max URL timeout in milliseconds (default '1400,1800')
--crop CROP <CROP> (optional, phantomjs only): rectangle <t,l,w,h> to crop the screen capture to (default to WINDOW_SIZE: '0,0,w,h'), only
numbers, w(idth) and h(eight). Ex. "10,20,w,h"
--custom-js CUSTOM_JS
<CUSTOM_JS> (optional, phantomjs only): path of a file containing JavaScript code to be executed before taking the screenshot. Ex:
js.txt
Screenshot label parameters:
-l, --label <LABEL> (optional): for each screenshot, create another one displaying inside the target URL (requires imagemagick)
Expand Down Expand Up @@ -192,6 +197,7 @@ Options not listed here below are supported by every current renderer
| | quality (`-q`) | [**Yes**](https://web.archive.org/web/20200111184123/https://phantomjs.org/api/webpage/method/render.html) | No | No
| | ajax and request timeouts (`--ajax-max-timeouts`) | **Yes** | No | No
| | crop (`--crop`) | [**Yes**](https://web.archive.org/web/20200111184050/https://phantomjs.org/api/webpage/property/clip-rect.html) | No | No
| | custom JavaScript (`--custom-js`) | [**Yes**](https://web.archive.org/web/20200823123026/https://phantomjs.org/api/webpage/method/evaluate-java-script.html) | No | No
| | | | | |
| **HTTP parameters** | | | | |
| | cookie (`-c`) | **Yes** | No | No |
Expand Down Expand Up @@ -222,6 +228,7 @@ Requirements

Changelog
---------
* version 2.94 - 08/23/2020: Added custom-js and single output file options
* version 2.93 - 08/16/2020: Added support of Python 3.8 and Microsoft Edge Chromium ; file output for failed webscreenshots ; filename length limitation for long URL
* version 2.92 - 06/21/2020: no_xserver option autodetection
* version 2.91 - 05/08/2020: Multiprotocol mode fix
Expand Down
19 changes: 16 additions & 3 deletions webscreenshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# along with webscreenshot. If not, see <http://www.gnu.org/licenses/>.
***/

var Page = (function(custom_headers, http_username, http_password, image_width, image_height, image_format, image_quality, ajax_timeout, max_timeout, crop_rect) {
var Page = (function(custom_headers, http_username, http_password, image_width, image_height, image_format, image_quality, ajax_timeout, max_timeout, crop_rect, custjs) {
var opts = {
width: image_width || 1200,
height: image_height || 800,
Expand Down Expand Up @@ -104,7 +104,12 @@ var Page = (function(custom_headers, http_username, http_password, image_width,
page.evaluate(function() {
document.body.bgColor = 'white';
});

if (custjs)
{
var fs = require('fs');
var content = fs.read(custjs);
page.evaluateJavaScript(content);
}
page.render(opts.file, {format: opts.format, quality: opts.quality});
phantom.exit(0);
}
Expand Down Expand Up @@ -147,6 +152,9 @@ function main() {

var p_crop = new RegExp('crop=(.*)');
var crop_rect = '';

var p_custjs = new RegExp('customjs=(.*)');
var custjs = '';

var temp_custom_headers = {
// Nullify Accept-Encoding header to disable compression (https://github.com/ariya/phantomjs/issues/10930)
Expand Down Expand Up @@ -219,6 +227,11 @@ function main() {
{
crop_rect = p_crop.exec(system.args[i])[1].split(',');
}

if (p_custjs.test(system.args[i]) === true)
{
custjs = p_custjs.exec(system.args[i])[1].split(',');
}
}

if (typeof(URL) === 'undefined' || URL.length == 0 || typeof(output_file) === 'undefined' || output_file.length == 0) {
Expand All @@ -228,7 +241,7 @@ function main() {
phantom.exit(1);
}
else {
var page = Page(temp_custom_headers, http_username, http_password, image_width, image_height, image_format, image_quality, ajax_timeout, max_timeout, crop_rect);
var page = Page(temp_custom_headers, http_username, http_password, image_width, image_height, image_format, image_quality, ajax_timeout, max_timeout, crop_rect, custjs);
page.render(URL, output_file);
}
}
Expand Down
42 changes: 36 additions & 6 deletions webscreenshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
izip = zip

# Script version
VERSION = '2.93'
VERSION = '2.94'

# Options definition
parser = argparse.ArgumentParser()
Expand All @@ -61,6 +61,7 @@
main_grp.add_argument('-w', '--workers', help = '<WORKERS> (optional): number of parallel execution workers (default 4)', default = 4)
main_grp.add_argument('-v', '--verbosity', help = '<VERBOSITY> (optional): verbosity level, repeat it to increase the level { -v INFO, -vv DEBUG } (default verbosity ERROR)', action = 'count', default = 0)
main_grp.add_argument('--no-error-file', help = '<NO_ERROR_FILE> (optional): do not write a file with the list of URL of failed screenshots (default false)', action = 'store_true', default = False)
main_grp.add_argument('-z', '--single-output-file', help = '<SINGLE_OUTPUT_FILE> (optional): name of a file which will be the single output of all inputs. Ex. test.png')

proc_grp = parser.add_argument_group('Input processing parameters')
proc_grp.add_argument('-p', '--port', help = '<PORT> (optional): use the specified port for each target in the input list. Ex: -p 80')
Expand All @@ -78,6 +79,7 @@
image_grp.add_argument('-q', '--quality', help = '<QUALITY> (optional, phantomjs only): specify the output image quality, an integer between 0 and 100 (default 75)', metavar="[0-100]", choices = range(0,101), type = int, default = 75)
image_grp.add_argument('--ajax-max-timeouts', help = '<AJAX_MAX_TIMEOUTS> (optional, phantomjs only): per AJAX request, and max URL timeout in milliseconds (default \'1400,1800\')', default = '1400,1800')
image_grp.add_argument('--crop', help = '<CROP> (optional, phantomjs only): rectangle <t,l,w,h> to crop the screen capture to (default to WINDOW_SIZE: \'0,0,w,h\'), only numbers, w(idth) and h(eight). Ex. "10,20,w,h"')
image_grp.add_argument('--custom-js', help = '<CUSTOM_JS> (optional, phantomjs only): path of a file containing JavaScript code to be executed before taking the screenshot. Ex: js.txt')

image_grp = parser.add_argument_group('Screenshot label parameters')
image_grp.add_argument('-l', '--label', help = '<LABEL> (optional): for each screenshot, create another one displaying inside the target URL (requires imagemagick)', action = 'store_true', default = False)
Expand Down Expand Up @@ -287,7 +289,7 @@ def extract_all_matched_named_groups(regex, match):
if matched_value != None: result[name] = matched_value

return result

def entry_format_validator(line):
"""
Validate the current line against several regexes and return matched parameters (ip, domain, port etc.)
Expand Down Expand Up @@ -380,6 +382,9 @@ def parse_targets(options):
return target_list

def craft_bin_path(options, context=CONTEXT_RENDERER):
"""
Craft the proper binary path for renderer
"""
global PHANTOMJS_BIN, CHROME_BIN, CHROMIUM_BIN, FIREFOX_BIN, XVFB_BIN, IMAGEMAGICK_BIN

final_bin = []
Expand Down Expand Up @@ -414,6 +419,9 @@ def craft_bin_path(options, context=CONTEXT_RENDERER):
return " ".join(final_bin)

def craft_arg(param):
"""
Craft arguments with proper quotes
"""
if is_windows():
return '%s' % param
else:
Expand All @@ -429,6 +437,23 @@ def launch_cmd(logger, url, cmd_parameters, options, context):

return execution_retval

def craft_output_filename_and_format(url, options):
"""
Craft the output filename and format
"""
output_format = options.format if options.renderer == 'phantomjs' else 'png'

if options.single_output_file:
if options.single_output_file.lower().endswith('.%s' % output_format):
output_filename = os.path.abspath(filter_bad_filename_chars_and_length(options.single_output_file))
else:
output_filename = os.path.abspath(filter_bad_filename_chars_and_length('%s.%s' % (options.single_output_file, output_format)))

else:
output_filename = os.path.join(options.output_directory, ('%s.%s' % (filter_bad_filename_chars_and_length(url), output_format)))

return output_format, output_filename

def craft_cmd(url_and_options):
"""
Craft the correct command with url and options
Expand All @@ -441,8 +466,7 @@ def craft_cmd(url_and_options):
logger_url.addHandler(logger_output)
logger_url.setLevel(options.log_level)

output_format = options.format if options.renderer == 'phantomjs' else 'png'
output_filename = os.path.join(options.output_directory, ('%s.%s' % (filter_bad_filename_chars_and_length(url), output_format)))
output_format, output_filename = craft_output_filename_and_format(url, options)

# PhantomJS renderer
if options.renderer == 'phantomjs':
Expand Down Expand Up @@ -470,8 +494,8 @@ def craft_cmd(url_and_options):
cmd_parameters.append('header="Authorization: Basic %s"' % basic_authentication_header)

width = options.window_size.split(',')[0]

height = options.window_size.split(',')[1]

cmd_parameters.append('width=%d' % int(width))
cmd_parameters.append('height=%d' % int(height))

Expand All @@ -488,6 +512,10 @@ def craft_cmd(url_and_options):
if options.header:
for header in options.header:
cmd_parameters.append('header="%s"' % header.rstrip(';'))

if options.custom_js and os.path.exists(options.custom_js):
cmd_parameters.append('customjs=%s' % craft_arg(os.path.abspath(options.custom_js)))


# Chrome and chromium renderers
elif (options.renderer == 'chrome') or (options.renderer == 'chromium') or (options.renderer == 'edgechromium'):
Expand Down Expand Up @@ -532,7 +560,6 @@ def craft_cmd(url_and_options):

return execution_retval, url


def take_screenshot(url_list, options):
"""
Launch the screenshot workers
Expand Down Expand Up @@ -592,6 +619,9 @@ def main():
if (options.input_file != None) and (options.URL != None):
parser.error('Please specify either an input file or an URL')

if options.single_output_file:
options.workers = 1

if options.output_directory != None:
options.output_directory = os.path.join(os_getcwd(), options.output_directory)
else:
Expand Down

0 comments on commit 16e5c2a

Please sign in to comment.