Browse Source

switch to playwright/firefox

Mike L 4 years ago
parent
commit
d3e99f1236
3 changed files with 43 additions and 24 deletions
  1. 19 10
      dist/webshot.js
  2. 1 0
      package.json
  3. 23 14
      src/webshot.ts

+ 19 - 10
dist/webshot.js

@@ -15,7 +15,7 @@ const child_process_1 = require("child_process");
 const fs_1 = require("fs");
 const html_entities_1 = require("html-entities");
 const pngjs_1 = require("pngjs");
-const puppeteer = require("puppeteer");
+const puppeteer = require("playwright");
 const sharp = require("sharp");
 const temp = require("temp");
 const util_1 = require("util");
@@ -37,11 +37,16 @@ const typeInZH = {
     animated_gif: ZHType('GIF'),
 };
 const logger = loggers_1.getLogger('webshot');
+const wsUrl = 'https://ilg-server.ling.uni-stuttgart.de/playwright-ws.json';
 class Webshot extends CallableInstance {
     constructor(mode, onready) {
         super('webshot');
-        // use local Chromium
-        this.connect = (onready) => puppeteer.connect({ browserURL: 'http://127.0.0.1:9222' })
+        this.connect = (onready) => axios_1.default.get(wsUrl)
+            .then(res => {
+            logger.info(`received websocket endpoint: ${JSON.stringify(res.data)}`);
+            const browserType = Object.keys(res.data)[0];
+            return puppeteer[browserType].connect({ wsEndpoint: res.data[browserType] });
+        })
             .then(browser => this.browser = browser)
             .then(() => {
             logger.info('launched puppeteer browser');
@@ -67,23 +72,27 @@ class Webshot extends CallableInstance {
                 const width = 720;
                 const zoomFactor = 2;
                 logger.info(`shooting ${width}*${height} webshot for ${url}`);
-                this.browser.newPage()
+                this.browser.newPage({
+                    bypassCSP: true,
+                    deviceScaleFactor: zoomFactor,
+                    locale: 'ja-JP',
+                    userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
+                })
                     .then(page => {
                     const startTime = new Date().getTime();
                     const getTimerTime = () => new Date().getTime() - startTime;
                     const getTimeout = () => Math.max(500, webshotDelay - getTimerTime());
-                    page.setUserAgent('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36')
-                        .then(() => page.setViewport({
+                    page.setViewportSize({
                         width: width / zoomFactor,
                         height: height / zoomFactor,
-                        isMobile: true,
-                        deviceScaleFactor: zoomFactor,
-                    }))
-                        .then(() => page.setBypassCSP(true))
+                    })
                         .then(() => page.goto(url, { waitUntil: 'load', timeout: getTimeout() }))
                         // hide header, "more options" button, like and retweet count
                         .then(() => page.addStyleTag({
                         content: 'header{display:none!important}path[d=\'M20.207 7.043a1 1 0 0 0-1.414 0L12 13.836 5.207 7.043a1 1 0 0 0-1.414 1.414l7.5 7.5a.996.996 0 0 0 1.414 0l7.5-7.5a1 1 0 0 0 0-1.414z\'],div[role=\'button\']{display: none;}',
+                    }))
+                        .then(() => page.addStyleTag({
+                        content: '*{font-family:-apple-system,SF Pro Display,Hiragino Sans,sans-serif!important}',
                     }))
                         // remove listeners
                         .then(() => page.evaluate(() => {

+ 1 - 0
package.json

@@ -35,6 +35,7 @@
     "html-entities": "^1.3.1",
     "log4js": "^6.3.0",
     "mirai-ts": "^0.7.4",
+    "playwright": "^1.9.1",
     "pngjs": "^5.0.0",
     "puppeteer": "^2.1.0",
     "read-all-stream": "^3.1.0",

+ 23 - 14
src/webshot.ts

@@ -4,8 +4,7 @@ import { spawnSync } from 'child_process';
 import { existsSync, readFileSync, statSync, unlinkSync, writeSync } from 'fs';
 import { XmlEntities } from 'html-entities';
 import { PNG } from 'pngjs';
-import * as puppeteer from 'puppeteer';
-import { Browser } from 'puppeteer';
+import * as puppeteer from 'playwright';
 import * as sharp from 'sharp';
 import { Readable } from 'stream';
 import * as temp from 'temp';
@@ -32,13 +31,15 @@ const typeInZH = {
 
 const logger = getLogger('webshot');
 
+const wsUrl = 'https://ilg-server.ling.uni-stuttgart.de/playwright-ws.json';
+
 class Webshot
 extends CallableInstance<
   [Tweets, (...args) => Promise<any>, (...args) => void, number],
   Promise<void>
 > {
 
-  private browser: Browser;
+  private browser: puppeteer.Browser;
   private mode: number;
 
   constructor(mode: number, onready?: () => any) {
@@ -51,8 +52,12 @@ extends CallableInstance<
     }
   }
 
-  // use local Chromium
-  private connect = (onready) => puppeteer.connect({browserURL: 'http://127.0.0.1:9222'})
+  private connect = (onready) => axios.get(wsUrl)
+  .then(res => {
+    logger.info(`received websocket endpoint: ${JSON.stringify(res.data)}`);
+    const browserType = Object.keys(res.data)[0];
+    return (puppeteer[browserType] as puppeteer.BrowserType<puppeteer.Browser>).connect({wsEndpoint: res.data[browserType]});
+  })
   .then(browser => this.browser = browser)
   .then(() => {
     logger.info('launched puppeteer browser');
@@ -80,24 +85,28 @@ extends CallableInstance<
       const width = 720;
       const zoomFactor = 2;
       logger.info(`shooting ${width}*${height} webshot for ${url}`);
-      this.browser.newPage()
+      this.browser.newPage({
+        bypassCSP: true,
+        deviceScaleFactor: zoomFactor,
+        locale: 'ja-JP',
+        userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
+      })
         .then(page => {
           const startTime = new Date().getTime();
           const getTimerTime = () => new Date().getTime() - startTime;
           const getTimeout = () => Math.max(500, webshotDelay - getTimerTime());
-          page.setUserAgent('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36')
-            .then(() => page.setViewport({
-              width: width / zoomFactor,
-              height: height / zoomFactor,
-              isMobile: true,
-              deviceScaleFactor: zoomFactor,
-            }))
-            .then(() => page.setBypassCSP(true))
+          page.setViewportSize({
+            width: width / zoomFactor,
+            height: height / zoomFactor,
+          })
             .then(() => page.goto(url, {waitUntil: 'load', timeout: getTimeout()}))
             // hide header, "more options" button, like and retweet count
             .then(() => page.addStyleTag({
               content: 'header{display:none!important}path[d=\'M20.207 7.043a1 1 0 0 0-1.414 0L12 13.836 5.207 7.043a1 1 0 0 0-1.414 1.414l7.5 7.5a.996.996 0 0 0 1.414 0l7.5-7.5a1 1 0 0 0 0-1.414z\'],div[role=\'button\']{display: none;}',
             }))
+            .then(() => page.addStyleTag({
+              content: '*{font-family:-apple-system,SF Pro Display,Hiragino Sans,sans-serif!important}',
+            }))
             // remove listeners
             .then(() => page.evaluate(() => {
               const poll = setInterval(() => {