Skip to content

Instantly share code, notes, and snippets.

@xiankai
Last active May 15, 2017 16:08
Show Gist options
  • Save xiankai/a39c9fdfaefabf8ec244c7461d558bba to your computer and use it in GitHub Desktop.
Save xiankai/a39c9fdfaefabf8ec244c7461d558bba to your computer and use it in GitHub Desktop.
/*
yarn add chrome-remote-interface
yarn add lighthouse
node run headless_chromium.js
*/
const chrome = require('chrome-remote-interface');
const { ChromeLauncher } = require('lighthouse/lighthouse-cli/chrome-launcher');
const _ = require('lodash');
function loadSubwayMenu(DOM) {
return DOM.getDocument()
.then(result => result.root.nodeId)
.then(nodeId => Promise.all([ // get subway categories
DOM.querySelectorAll({ nodeId, selector: '.SubGroup' }),
DOM.querySelectorAll({ nodeId, selector: '.SubGroup.NotSub' })
]))
.then(([
allGroups,
notSubs
]) => Promise.all( // narrow to meals
_.difference(allGroups.nodeIds, notSubs.nodeIds)
.map(nodeId => DOM.querySelectorAll({ nodeId, selector: '#lnk_ItemUrlImage' }))
))
.then(nodeIdsCollection => _.flatMap(nodeIdsCollection, ({ nodeIds }) => nodeIds))
.then(nodeIds => Promise.all(
nodeIds.map(nodeId => DOM.getAttributes({ nodeId }))
))
.then(nodeAttributes => nodeAttributes.map(({ attributes }) => attributes[attributes.indexOf('href') + 1]))
.then(result => console.log(result))
.catch((err) => {
console.error(err);
});
}
/**
* Launches a debugging instance of Chrome on port 9222.
* @param {boolean=} headless True (default) to launch Chrome in headless mode.
* Set to false to launch Chrome normally.
* @return {Promise<ChromeLauncher>}
*/
function launchChrome(headless = true) {
const launcher = new ChromeLauncher({
port: 9222,
autoSelectChrome: true, // False to manually select which Chrome install.
additionalFlags: [
'--window-size=412,732',
'--disable-gpu',
headless ? '--headless' : '',
],
});
return launcher.run().then(() => launcher)
.catch(err => launcher.kill().then(() => { // Kill Chrome if there's an error.
throw err;
}, console.error));
}
launchChrome().then((launcher) => {
chrome((protocol) => {
// Extract the parts of the DevTools protocol we need for the task.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const { Page, DOM } = protocol;
// First, need to enable the domains we're going to use.
Promise.all([
Page.enable(),
DOM.enable()
]).then(() => {
Page.navigate({ url: 'https://www.subway.com.au/menu' });
// Wait for window.onload before doing stuff.
Page.loadEventFired(() => {
onPageLoad(DOM).then(() => {
protocol.close();
launcher.kill(); // Kill Chrome.
});
});
});
}).on('error', (err) => {
throw Error(`Cannot connect to Chrome:${err}`);
});
});
/*
yarn add phantomjs-prebuilt
yarn phantomjs phantomjs_with_jquery.js
*/
const webpage = require('webpage');
function onPageLoad() {
return $('.SubGroup').not('.NotSub').find('#lnk_ItemUrlImage').map(function(i, ele) {
return $(ele).attr('href');
}).get();
}
const page = webpage.create();
page.open('https://www.subway.com.au/menu', function(status) {
if (status !== 'success') {
console.log('Unable to access network');
} else if (page.injectJs('jquery.js')) {
try {
const links = page.evaluate(onPageLoad);
console.log(links);
} catch (err) {
console.error(err);
}
phantom.exit();
} else {
console.log('Unable to inject jQuery');
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment