Новости
- Перевірка якості скріншотів
- Тільки видима область
- невірний resize
- "Що я взагалі сдесь роблю" © Zombie
- Фальшиві паспорти - старий гугл
- Пикселизация - виколи очі.
- Результати першого заїзду
- Перевірка швидкості роботи браузерів
- Time
- Аналіз витрат ресурсів на створення скріншота
- ненаситне привид
- лукавий хитрун
- Загальні витрати пам'яті
- Memory max
- Методи управління браузерами
- Firefox
- Phantom
- Slimer
власний проект WB -Tech з коментування скріншотів coment.me на сьогоднішній день, для отримання знімка сайту використовує зв'язку selenium + firefox. Даний підхід вирішує завдання отримання скріншота, проте витрачає досить багато пам'яті, і до того ж з часом накопичується велика кількість завислих процесів, що в свою чергу призводить до підвисання сервісу. У зв'язку з цим, необхідно досліджувати доступні варіанти і визначити найкращий з браузерів для автоматичного створення скріншотів.
Критерії для вибору переможця будуть являтся:
- якість скріншотів
- Швидкість роботи
- витрачаються ресурси
На участь в ралі були відібрані наступні кандидати:
Познайомимося з учасниками ближче:
- Firefox - Найбільш масово не WebKit браузер на сьогоднішній день.
- Google Chrome / Chromium - Один з найшвидших і популярних браузерів.
- Splash - легкий браузер з підтримкою javascript реалізовиннй на python-е предоставляюшій для управління http api.
- Ghost.py - python браузер з підтримкою javascript орієнтований на автоматичне функціональне тестування.
- Zombie.js - легкий і швидкий безголовий браузер для автоматичного тестування заснований на node.js.
- Phantom.js - швидкий безголовий браузер на движку WebKit з вбудованою підтримкою svg. Управляється за допомогою javascript api.
- Slimer.js - швидкий браузер, схожий на phantom.js, проте використовує движок Gecko від firefox. Управляється за допомогою javascript api.
Отже, учасники відібрані, і готові показати себе у всій красі, що ж - приступимо до змагань.
Нашим чудовим конкурсантам належить пройти трек по пересіченій місцевості з чотирма крутими поворотами з 16-ю чекпоінти, а саме: показати свої навички на наступних ресурсах:
при наступних дозволах екранів по ширині: 240, 780 1320, 1920 пікселів.
Перевірка якості скріншотів
Якість - це робити що-небудь правильно, навіть коли ніхто не дивиться.
Оскільки, в кінцевому рахунку, результат повинен бути не гірше, ніж наявний на даний момент - еталоном якості виступатимуть знімки firefox-а.
На даному етапі зійшли з дистанції відразу 4 учасники. Причому, якби я робив ставки, то програв би, адже хром, якого я вважав фаворитом змагань, виявився абсолютно некомпетентним учасником.
Тільки видима область
Для зв'язки selenium-а і google chrome необхідно використовувати chromedriver поточна стабільна версія 2.14. І, як виявилося, в ньому міститься баг, який тягнеться з 2013 року, відомим issue . Хром драйвер не перегортає вікно браузера при захопленні зображення, а робить знімок видимій області.
Так що Google Chrome і Chromium не пройшли даний етап.
невірний resize
Безголовий браузер Splash, запускається демоном і слухає localhost: 8050, за яким надає http api управління браузером. Для збереження скріншота необхідно вказати адресу сайту і ширину вікна браузера.
request = 'http: // localhost: 8050 / render.png? url = {url} & width = {res} & render_all = 1 & wait = 1'. format (url = url, res = res) res = subprocess. check_call ([ 'curl', request, '-o', save_as])
Однак, як виявилося, ширина вікна браузера завжди 1024px, а параметр width впливає тільки на фактичну ширину отриманого зображення, до того ж стисненого як thumbnail.
240px
780px
Так що splash не пройшов даний етап.
"Що я взагалі сдесь роблю" © Zombie
Як виявилося, Зомбі взагалі не вміє робити скріншоти, тому вибуває зі змагань.
Фальшиві паспорти - старий гугл
Деякі з учасників змагань, а саме Phantom.js і Slimer.js не змогли б пройти всі етапи ралі, під своїми іменами, тому довелося видати їм фальшиві паспорти.
Google видає різні версії сайту, в залежності від того: який user agent у браузера запитувача сторінку, і якщо цей агент невідомий або старий, то видається стара версія google, з чорною смужкою меню.
Phantom.js 240px
Slimer.js 240px
Але при використанні підроблених паспортів, від firefox результат такої як потрібно.
'Mozilla / 5.0 (X11; Linux x86_64) Gecko / 20100101 Firefox / 36.0'
Пикселизация - виколи очі.
Ghost.py не дуже добре вміє захоплювати картинки, логотип google виглядає схожим на паркан.
Хоч це і неприпустимо, однак, обмежимося попередженням, і припустимо Ghost.py в наступний тур.
Результати першого заїзду
До другого туру пройшли 4 учасники та 4 учасники покинули змагання. Турнірна таблиця після закінчення першого етапу.
- Firefox
- Pantom.js
- Slimer.js
- Ghost.py
- Chromium
- Google Chrome
- Splash
- Zombie.js
Перевірка швидкості роботи браузерів
На даному етапі вимірювалося час, необхідний для створення браузера, відкриття потрібної сторінки, зміни ширини вікна до заданої, збереження сторінки як зображення PNG, закриття сторінки і знищення об'єкта браузера.
Виміри проводилися за допомогою стандартної бібліотеки time, як різниця часу між початком запуску функції і її закінчення.
import time # ... start = time. time () # call test browser fun () end = time. time () # ... times. append (end - start)
легенда:
Time
Результати другого заїзду
В ході даного етапу учасники зайняли наступні місця:
- Phantom.js 2.x
- Phantom.js 1.x
- Ghost.py
- Phantom.js 1.x + selenium
- Phantom.js 2.x + selenium
- Slimer.js 9.x
- Slimer.js 10.x
- Firefox + selenium
В результаті, жоден з учасників не виявився значно гірше ніж firefox, тому що вибули немає, всі переходять до наступного етапу.
Аналіз витрат ресурсів на створення скріншота
Враховувалася пам'ять, яку витрачає головний процес, і все його дочірні процеси. Пам'ять вимірювалася за допомогою функції memory_usage бібліотеки memory_profiler із зазначенням параметра include_children.
Вимірювалася мінімальна, середня і максимальна пам'ять для кожного скріншота.
from memory_profiler import memory_usage # ... memory = memory_usage ((fun, args), include_children = True) # ... mins. append (min (memory)) maxs. append (max (memory)) avgs. append (avg (memory))
ненаситне привид
Ghost.py виявився надзвичайно ненажерливим, займаючи всю доступну пам'ять, доходив до максимуму і вилітав. Єдиний з учасників, хто не зумів пройти всі 16 чекпоінтів за один підхід.
З огляду на винесене раніше попередження, привид вилітає з конкурсу!
I is not afraid of no ghosts
лукавий хитрун
Виявилося, що Slimer.js прикидається: запускається дочірній процес slimerjs, який споживає не більше 3 Mb пам'яті, але при цьому запускає ще один дочірній процес з ім'ям firefox, який вже добирає пам'ять до 300 Mb.
Загальні витрати пам'яті
Оскільки Ghost.py споживає аж надто багато ресурсів, на графіках не вказується.
легенда:
Memory max
Memory avg
Результати третього заїзду
В ході даного етапу учасники зайняли наступні місця:
- Phantom.js 1.x
- Phantom.js 2.x
- Phantom.js 1.x + selenium
- Phantom.js 2.x + selenium
- Slimer.js 9.x
- Slimer.js 10.x
- Firefox + selenium
- Ghost.py
На цьому етапі вибуває Ghost.py, турнірна таблиця приймає вид:
- Pantom.js
- Slimer.js
- Firefox
- Ghost.py
Методи управління браузерами
Незважаючи на те, що визначилася трійка лідерів і вже можна підвести підсумки, розглянемо як управляти безголовими браузерами.
Firefox
Firefox працює в зв'язці з selenium-му і управляється досить просто, єдина особливість - це те, що браузер запускає графічну оболонку, тому потрібно використовувати віртуальний дисплей.
from selenium import webdriver from pyvirtualdisplay import Display # ... with Display (visible = 0, size = (1024, 768), backend = 'xvfb'): browser = Browser (** param) browser. set_window_size (width, 768) browser. get (url) browser. save_screenshot (save_as) browser. quit ()
Phantom
Phantom.js можна використовувати, як самостійний безголовий браузер, так і в зв'язці з selenium-му. Робота з selenium-му аналогічна firefox, за тим лише винятком, що немає необхідності запускати віртуальний дисплей.
Власна робота phantom.js, полягає у виклику консольної команди, і передачу їй скрипта для виконання браузером.
var page = require ( 'webpage'). create (); page. settings. userAgent = 'Mozilla / 5.0 (X11; Linux x86_64) Firefox / 36.0'; page. viewportSize = {width: 1920 році, height: 768}; page. open ( 'http://wbtech.pro/', function (status) {page. render ( 'img / phantomjs2-no_selenium / wbtech.pro-1920px.png'); phantom. exit ();});
У python запускаємо браузер за допомогою стандартної бібліотеки subprocess.
import subprocess # ... subprocess. check_call ([phantom_path, script_path, '--ssl-protocol = any'])
Slimer
Slimer.js працює точно так само, як і phantom.js без selenium-а, але є не зовсім безголовим, він запускає графічну оболонку, тому вимагає віртуальний дисплей.
А так же, в ході тестування було виявлено , Що для коректного скриншота потрібно завжди, перед відкриттям сторінки, вказувати базову ширину вікна браузера.
var page = require ( 'webpage'). create (); page. viewportSize = {width: 1024, height: 768}; page. settings. userAgent = 'Mozilla / 5.0 (X11; Linux x86_64) Firefox / 36.0'; page. open ( 'http://wbtech.pro/', function (status) {page. viewportSize = {width: 1920 році, height: 768}; page. render ( 'img / slimerjs10 / wbtech.pro-1920px.png') ; page. close (); slimer. exit ();});
У python запускаємо браузер за допомогою стандартної бібліотеки subprocess.
from pyvirtualdisplay import Display import subprocess # ... with Display (visible = 0, size = (1024, 768), backend = 'xvfb'): subprocess. check_call ([slimer_path, script_path, '--ssl-protocol = any'])
Гонка завершилася, настав час підбити підсумки і визначити переможців.
До фінішу доїхали всього три команди, так що трійка лідерів очевидна. З огляду на витрати ресурсів і часу, учасники займають наступні місця:
- Phantom.js 2.x
- Phantom.js 1.x
- Phantom.js 1.x + selenium
- Phantom.js 2.x + selenium
- Slimer.js 9.x
- Slimer.js 10.x
- Firefox + selenium
Беззаперечним лідером перегонів став phantom.js, в якості нагороди йому буде запропоновано обійняти посаду firefox-а на сервісі coment.me .
Png?