Mojo :: useragent и javascript

Мне интересно, можно ли сделать что-то подобное с Mojo :: UserAgent:

скажем, у меня есть следующий код:

my $ua  = Mojo::UserAgent->new;
my $res = $ua->get('mojolicious.org/perldoc')->result;

можно ли перехватить запрос Mojo :: UserAgent и отправить его другому веб-клиенту, который знает javascript, где его результат отправляется обратно как Mojo :: Transaction :: HTTP ($ res выше), где пользователь может продолжать использовать Mojo :: UserAgent результаты интерфейса.

то есть я хочу следующее:

Mojo :: UserAgent-> HTTP-запрос -> перехватить HTTP-запрос -> Отправить HTTP-запрос на поддержку javascript веб-клиента, например WWW :: Chrome :: Mechanize или FireFox :: Marionette -> веб-клиент JavaScript выполнит запрос -> возвращенный результат перехвачен и изменен на Mojo :: Transaction :: HTTP

или

Mojo :: UserAgent -> неблокирующий HTTP-запрос -> неблокирующий HTTP-ответ -> отправить во встроенный веб-браузер, например webkit -> получить результат как Mojo :: Transaction :: HTTP

Есть идеи / примеры, как позволить Mojo :: UserAgent работать с javascript?

9
0
441
2

Ответы 2

Это почти всегда возможно, но на самом деле вопрос в том, сколько работы вы бы сделали для этого. Частью этого конкретного ответа является то, как вы хотите перехватывать запросы. Это простая часть, потому что вы можете обернуть метод start (как это делает Mojo :: UserAgent :: Role :: В очереди).

После того, как вы перехватили запрос, делайте все, что хотите. Получите необработанный ответ и пусть Mojo проанализирует его и построит эту часть транзакции. После этого вы снова входите в нормальную прогрессию.

Некоторое время люди рекомендовали безголовый браузер фантомы, но похоже, что этот проект застопорился. Есть Моджо :: Призрак Джоэла Бергера, но это не совсем то, что вам нужно.

Наконец, помните, что почти все хотели бы, чтобы это существовало, но это не так. Это важная информация. ;)

Если вы все еще хотите работать над этим, задавая более узкие вопросы по ходу дела, вероятно, больше поможет.

Удачи!

Не совсем то, что вы просили, но, вероятно, достаточно близко можно было бы достичь:

  • установка хромированного безголового
  • настройка nodejs + пара модулей
  • получение загруженных и проанализированных событий на стороне клиента externalHTML
  • чтение из кода perl внешнего HTML

следующее:

# just a perl oneliner, parsing the scrapped html and passing it to Mojo::DOM
perl -MMojo::DOM -e '$s=`node scrap-html.js`; for my $e (Mojo::DOM->new($s)->find("html body a.scroll")->each){ print $e->text}';

где код для scrap-html.js

  // file: scrap-html.js src: https://gist.github.com/magician11/a979906401591440bd6140bd14260578
  const CDP = require('chrome-remote-interface');
  const chromeLauncher = require('chrome-launcher');

  (async function() {
    const launchChrome = () =>
      chromeLauncher.launch({ chromeFlags: ['--disable-gpu', '--headless','--blink-settings=imagesEnabled=false'] });

    const chrome = await launchChrome();
    const protocol = await CDP({ port: chrome.port });
    const timeout = ms => new Promise(resolve => setTimeout(resolve, ms));

    // See API docs: https://chromedevtools.github.io/devtools-protocol/
    const { Page, Runtime, DOM } = protocol;
    await Promise.all([Page.enable(), Runtime.enable(), DOM.enable()]);

    uri = 'https://qto.fi/qto/view/readme_doc'
    Page.navigate({ url: uri });

    // wait until the page says it's loaded...
    Page.loadEventFired(async () => {
      try {
        await timeout(4000); // give the JS some time to load

        // get the page source
        const rootNode = await DOM.getDocument({ depth: -1 });
        const pageSource = await DOM.getOuterHTML({
          nodeId: rootNode.root.nodeId
        });
        protocol.close();
        chrome.kill();
        console.log ( pageSource.outerHTML)
      } catch (err) {
        console.log(err);
      }
    });
  })();
  //eof file: scrap-html.js

пример для всей настройки на ubuntu:

  # start install chromium-headless
  sudo apt-get update
  sudo apt-get install -y software-properties-common
  sudo apt-get install -y chromium-browser
  sudo apt-get update

  wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
  sudo dpkg -i google-chrome-stable_current_amd64.deb
  apt --fix-broken install
  # stop install chromium-headless
  # start installing the nodejs + node modules
  sudo apt install nodejs
  sudo npm install -g chrome-remote-interface
  sudo npm install -g chrome-launcher
  export NODE_PATH=/usr/local/lib/node_modules
  # stop installing the nodejs + modules

Другие вопросы по теме