In case you have IE >=9 compatible with DOMParser, you can simply read and parse page like this.
In Chrome & FF you end-up with CORS problem.
But same logic can be used in monkey - song name is in 1 of 2 H1 tags, band name in 1st H2 and song inside P tags block with a DIV around.
Or also in node.js you can do it similar way without CORS problem including file access, etc.
<script>
loadPage("https://www.letras.mus.br/queen/64295/");
function loadPage(url) {
var http = new XMLHttpRequest();
http.open('GET', url, true);
http.onloadend = function () {
var html = new DOMParser().parseFromString(this.responseText, "text/html")
html = html.documentElement;
var el = html.getElementsByTagName("H1");
var interesting = el[el.length-1].outerHTML + "\n";
el = html.getElementsByTagName("H2")[0];
el.innerHTML = el.innerText;
interesting += el.outerHTML + "\n";
interesting += html.getElementsByTagName("P")[0].parentElement.innerHTML
document.write(
"<style>\nbody { background-color:transparent; font-family:Arial, sans-serif; font-size:19px; opacity:1; word-wrap:break-word; margin:0px; }\n" +
"h1 { color: rgb(255, 102, 0); font-size: 25px; font-weight: 700; letter-spacing: -1px; margin:0px; }\n" +
"h2,a { color:rgb(183, 183, 0); font-size: 19px; font-weight: 700; letter-spacing: -1px; text-decoration: none; margin:0px; }\n" +
"p { color: rgb(68, 68, 68); font-weight: 400; line-height: 30.4px; margin-bottom: 30.4px; }\n</style>\n"
+ interesting);
document.close();
}
http.send();
}
</script>
And here node.js version saving content you are looking for to file:
const request = require('request');
const jsdom = require("jsdom");
var fs = require('fs');
loader("https://www.letras.mus.br/queen/64295/");
function processDOM(body) {
var dom = new jsdom.JSDOM(body);
var html = dom.window.document;
// Song name
var el = html.querySelectorAll("H1");
el = el[el.length - 1];
var items = [el.textContent];
var interesting = "<style>\nbody { background-color:transparent; font-family:Arial, sans-serif; font-size:19px; opacity:1; word-wrap:break-word; margin:0px; }\n" +
"h1 { color: rgb(255, 102, 0); font-size: 25px; font-weight: 700; letter-spacing: -1px; margin:0px; }\n" +
"h2,a { color:rgb(183, 183, 0); font-size: 19px; font-weight: 700; letter-spacing: -1px; text-decoration: none; margin:0px; }\n" +
"p { color: rgb(68, 68, 68); font-weight: 400; line-height: 30.4px; margin-bottom: 30.4px; }\n</style>\n" +
el.outerHTML + "\n";
// Band
el = html.querySelector("H2");
items.push(el.textContent.trim());
el.innerHTML = items[1];
interesting += el.outerHTML + "\n";
// Lyrics
el = html.querySelector("P").parentElement.innerHTML;
interesting += el.replace(/<br>/g, '<br>\n').replace(/<\/p>/g, '</p>\n');
items.push(interesting);
return items;
}
// Based on https://stackoverflow.com/questions/38428027/why-await-is-not-working-for-node-request-module#38428075
async function loader(url) {
var res = await doRequest(url);
// Save new simple page
var pageName = res[0].replace(/\s/g, '_') + ".htm"; // song_name.htm
fs.writeFile(pageName, res[2], function (err) { // html data
if (err) throw err;
console.log(pageName + ' saved.');
});
}
function doRequest(url) {
return new Promise(function (resolve, reject) {
request(url, function (error, res, body) {
if (!error && res.statusCode == 200) {
resolve(processDOM(body));
} else {
reject(error);
}
});
});
}
Small sugar - element computed style printer - it will create empty element, get computed styles of your and print different values.
var el=prompt('Element:',"body"), defaultStyles, computedStyles;
defaultStyles = getStyles({}, window.getComputedStyle(document.createElement(el)));
computedStyles = el + ' ' + JSON.stringify(getStyles(defaultStyles, window.getComputedStyle(document.querySelector(el))), null, 3)
.replace(/\"([^\"]+)\": \"([^\"]+)\",/g,"$1: $2;").replace(/\n/g, "\r\n");
function getStyles(defaultStyles, computedStyles) {
var content = {};
for (var i=0; i<computedStyles.length; i++) {
cssProperty = computedStyles[i];
cssValue = computedStyles.getPropertyValue(cssProperty);
if(defaultStyles[cssProperty] != cssValue)
content[cssProperty] = cssValue;
}
return content;
}
console.log(computedStyles)
//prompt('Styles: ', computedStyles);
prompt("Copy bookmarklet:", 'javascript:var el=prompt("Element:","body"), defaultStyles, computedStyles;defaultStyles = getStyles({}, window.getComputedStyle(document.createElement(el)));computedStyles = el + " " + JSON.stringify(getStyles(defaultStyles, window.getComputedStyle(document.querySelector(el))), null, 3).replace(/\\"([^\\"]+)\\": \\"([^\\"]+)\\",/g,"$1: $2;").replace(/\\n/g, "\\r\\n");function getStyles(defaultStyles, computedStyles) {var content = {};for (var i=0; i<computedStyles.length; i++) {cssProperty = computedStyles[i];cssValue = computedStyles.getPropertyValue(cssProperty);if(defaultStyles[cssProperty] != cssValue)content[cssProperty] = cssValue;}return content;}prompt("Styles: ", computedStyles),undefined')