Closed Parvares closed 2 years ago
Something like...
document.querySelectorAll(".titololistarisultati a[href][title]").forEach( a => {
window.open(a.href,"_blank");
});
Great, really useful for me, thanks very much!!! Is there a way to gather all the resulting tabs/pages in only one long page? Would be perfect!
What part of the results page are you wanting on one page?
Possibly a web page with 15 records for every page... Thanks!
( async() => {
let links = [...document.querySelectorAll(".titololistarisultati a[href][title]")];
for ( let i in links ) {
let link = links[i];
let f = document.createElement('iframe');
f.style.display = 'none';
document.body.appendChild(f);
f.onload = async () => {
await new Promise(r => setTimeout(r, 100));
f.contentWindow.document.getElementById("tabDocument_item_tabcata").click();
await new Promise(r => setTimeout(r, 100));
let tab = f.contentWindow.document.getElementById("tabcata");
let content = tab.outerHTML;
document.querySelector(`#listadocumenti_${i}`).innerHTML = content;
}
f.src = link.href;
await new Promise(r => setTimeout(r, 100));
}
})();
Be aware, it takes time to load all those iframes
Incredible, works like a charm, thanks really so much! Is it possible to have the same result when I pass from page 1 (with 15 results) to page 2 (with other 15 results), to page 3, and so on? I've tried right clicking on page 2 using your extension, the detailed records still open in one page, but they are not related with the search term... Thanks again!
The Post-Search script will only run once, on the results landing page ( page 1 of results ). To run the script anywhere else, you might try copying it to a new Script-type engine, and click that engine when you go to the next page. Or, bind a hotkey to that engine and just press a button to run the script after you navigate to the next page.
This may be a task better suited for tampermonkey. I'm guessing you could reuse that script and have it run on every results page
Thanks Mike, should I fill the metadata 1-10? Thanks again!
Should I fill the metadata
You should definitely restrict it to running on https://www.bibliotechediroma.it/opac/query/*
It worked for me using
// ==UserScript==
// @name New Userscript
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://www.bibliotechediroma.it/opac/query/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=bibliotechediroma.it
// @grant none
// ==/UserScript==
(function() {
'use strict';
( async() => {
let links = [...document.querySelectorAll(".titololistarisultati a[href][title]")];
for ( let i in links ) {
let link = links[i];
let f = document.createElement('iframe');
f.style.display = 'none';
document.body.appendChild(f);
f.onload = async () => {
await new Promise(r => setTimeout(r, 100));
f.contentWindow.document.getElementById("tabDocument_item_tabcata").click();
await new Promise(r => setTimeout(r, 100));
let tab = f.contentWindow.document.getElementById("tabcata");
let content = tab.outerHTML;
document.querySelector(`#listadocumenti_${i}`).innerHTML = content;
}
f.src = link.href;
await new Promise(r => setTimeout(r, 100));
}
})();
})();
I also set the following
If you use that script, remove the Post-Search Script from that engine
Actually, I take that back. I'm not getting the changes when going to another page. You might need more code for that
Okay, thanks again, now it works with Tampermonkey following your settings. I noticed the script only works with your extension, is it possible let the script work with and without your extension (directly in the search engine)?
Try this in tampermonkey
// ==UserScript==
// @name New Userscript
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://www.bibliotechediroma.it/opac/query/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=bibliotechediroma.it
// @grant none
// ==/UserScript==
(function() {
'use strict';
let url = window.location.href;
const main = async() => {
let links = [...document.querySelectorAll(".titololistarisultati a[href][title]")];
let startIndex = (() => {
let id = document.querySelector(".list-document > LI").id;
return parseInt(id.match(/listadocumenti_(\d+)/)[1]);
})();
//console.log('start index', startIndex);
for ( let i in links ) {
try {
let link = links[i];
let index = parseInt(i) + parseInt(startIndex);
//console.log("index: " + index, link.href);
let f = document.createElement('iframe');
f.style.display = 'none';
document.body.appendChild(f);
f.onload = async () => {
try {
await new Promise(r => setInterval(() => {
if ( f.contentWindow.document.getElementById("tabDocument_item_tabcata") )
r();
}, 100));
f.contentWindow.document.getElementById("tabDocument_item_tabcata").click();
await new Promise(r => setTimeout(r, 100));
let tab = f.contentWindow.document.getElementById("tabcata");
let content = tab.outerHTML;
document.querySelector(`#listadocumenti_${index}`).innerHTML = content;
} catch (error) { console.log(error)}
}
f.src = link.href;
} catch (error) {
console.log(error);
}
await new Promise(r => setTimeout(r, 100));
}
}
main();
setInterval(() => {
if ( window.location.href !== url ) {
//console.log('href change');
url = window.location.href;
main();
}
}, 1000);
})();
Absolutely astonishing, thanks so much, Mike, it's all working perfectly!! P.S. Is this warning important in line 44? eslint: curly - expected { after 'if' condition
Is this warning important in line 44?
Nah, just a style choice that particular linter config doesn't like. You could rewrite that line as the following and get rid of the warning, but it makes no difference in the code.
if ( f.contentWindow.document.getElementById("tabDocument_item_tabcata") ) {
r();
}
Great, thanks again for you time!!
Hi Mike, may I ask a little variotion on this script? Is it possible to have the same kind of list (15 records per page), but getting from the single records not the tab "Scheda" as in the above script, but the tab "Lo trovi in", possibly opening the label "Biblioteca Morante"? Thanks ever so much!
The difference would be with this line
f.contentWindow.document.getElementById("tabDocument_item_tabcata").click();
That's where the Scheda tab is clicked. Simply omit that line or comment it out with //
to see the Lo Trovi in tab, since it's the default shown. Clicking the "Biblioteca Elsa Morante" would be done in the same manner. You just need to replace tabDocument_item_tabcata" with the proper selector. You can inspect the DOM in the browser with CTRL+SHIFT+I to find a selector that works ( usually the id of the element to be clicked ) . I'll check myself later if you haven't found a solution.
Mhm, thank you, but didn't solve.
Do you have a link to a page with a "Biblioteca Elsa Morante" tab? I'm not sure what search would get me a link that does.
Nevermind, I found it.
Try this selector
document.querySelector('#biblioteche [onclick*="Morante"]').click();
Sorry Mike, the result is the same.
I'll check it out. It's the holidays here so I've been preoccupied.
I'm really not sure what you're trying to achieve, but this script will "click" a Biblioteca Elsa Morante tab, if one exists, and display that instead of the Scheda tab
// ==UserScript==
// @name New Userscript
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://www.bibliotechediroma.it/opac/query/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=bibliotechediroma.it
// @grant none
// ==/UserScript==
(function() {
'use strict';
let url = window.location.href;
const main = async() => {
let links = [...document.querySelectorAll(".titololistarisultati a[href][title]")];
let startIndex = (() => {
let id = document.querySelector(".list-document > LI").id;
return parseInt(id.match(/listadocumenti_(\d+)/)[1]);
})();
//console.log('start index', startIndex);
for ( let i in links ) {
try {
let link = links[i];
let index = parseInt(i) + parseInt(startIndex);
//console.log("index: " + index, link.href);
let f = document.createElement('iframe');
f.style.display = 'none';
document.body.appendChild(f);
f.onload = async () => {
try {
await new Promise(r => setInterval(() => {
if ( f.contentWindow.document.getElementById("tabDocument_item_tabcata") )
r();
}, 100));
let tab;
let morante = f.contentWindow.document.querySelector('#biblioteche [onclick*="Morante"]');
if ( morante ) {
morante.click();
await new Promise(r => setTimeout(r, 100));
tab = f.contentWindow.document.getElementById("tabloca");
} else {
f.contentWindow.document.getElementById("tabDocument_item_tabcata").click();
await new Promise(r => setTimeout(r, 100));
tab = f.contentWindow.document.getElementById("tabcata");
}
let content = tab.outerHTML;
document.querySelector(`#listadocumenti_${index}`).innerHTML = content;
} catch (error) { console.log(error)}
}
f.src = link.href;
} catch (error) {
console.log(error);
}
await new Promise(r => setTimeout(r, 100));
}
}
main();
setInterval(() => {
if ( window.location.href !== url ) {
//console.log('href change');
url = window.location.href;
main();
}
}, 1000);
})();
Thanks for your reply, Mike, and thanks for your time! The results are a bit confusing, even filtering upstream by library and type of resource ("Libri moderni", so avoiding ebooks, that are without localization).
If you're just wanting the listings of the original search page replaced with the content of the result page links, that's easy enough. The problem is, the "tabs" will most likely not be clickable because the events won't be copied when displayed on the original results page. So you either need to "click" them programmatically before displaying them, or load each result link into an iframe and display the iframe on the original results page. Again, I don't know what you're doing after getting the results, so I can't say which approach is better.
Hi, I need the title (doesn't matter the abstract) and the inventory part of the library for every 15 records Thanks again!
From the queries I've run, not every result has a "Biblioteca Morante" tab, so how would the results look then?
Doesn't matter, moreover I can filter (upstream or downstream) the results by library.
I tested the iframe method and it doesn't seem to work. The host site throws some errors, so you might be stuck copying the DOM and pasting it into the results page.
Are you just trying to get this content to display on the main results page?
Inventario 58452
Collocazione ADO 813.5 KIN
// ==UserScript==
// @name New Userscript
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://www.bibliotechediroma.it/opac/query/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=bibliotechediroma.it
// @grant none
// ==/UserScript==
// https://www.bibliotechediroma.it/opac/query/stephen%20king?context=tmatm
(function() {
'use strict';
let url = window.location.href;
const main = async() => {
let links = [...document.querySelectorAll(".titololistarisultati a[href][title]")];
let startIndex = (() => {
let id = document.querySelector(".list-document > LI").id;
return parseInt(id.match(/listadocumenti_(\d+)/)[1]);
})();
//console.log('start index', startIndex);
for ( let i in links ) {
try {
let link = links[i];
let index = parseInt(i) + parseInt(startIndex);
//console.log("index: " + index, link.href);
let f = document.createElement('iframe');
f.style.display = 'none';
document.body.appendChild(f);
f.onload = async () => {
try {
await new Promise(r => setInterval(() => {
if ( f.contentWindow.document.getElementById("tabDocument_item_tabcata") )
r();
}, 100));
let tab;
let inventario;
let morante = f.contentWindow.document.querySelector('#biblioteche [onclick*="Morante"]');
if ( morante ) {
morante.click();
await new Promise(r => setTimeout(r, 100));
tab = f.contentWindow.document.querySelector('.inventario');
} else {
return;
// f.contentWindow.document.getElementById("tabDocument_item_tabcata").click();
// await new Promise(r => setTimeout(r, 100));
// tab = f.contentWindow.document.getElementById("tabcata");
}
let li = document.querySelector(`#listadocumenti_${index}`)
let content = tab.outerHTML;
li.appendChild(tab);
//li.innerHTML = content;
//li.style.borderBottom = 'none';
} catch (error) { console.log(error)}
}
f.src = link.href;
} catch (error) {
console.log(error);
}
await new Promise(r => setTimeout(r, 100));
}
}
main();
setInterval(() => {
if ( window.location.href !== url ) {
//console.log('href change');
url = window.location.href;
main();
}
}, 1000);
})();
Wao, thanks, the results seem almost perfect! Yes, that was what I expected, except the strange fact that not every record display the iframe. Thanks again!
except the strange fact that not every "Biblioteca Morante" record display the iframe. Isn't it there a workaround that comes to your mind? Thanks again!
Do you have an example URL I can look at?
Do you have an example URL I can look at?
Sorry, what do you mean? Some record that doesn't display the iframe?
If you perform a search and see a results page where not every Biblioteca Morante result is displayed properly, copy the URL and and paste it here so I can see what you're seeing.
Gotcha. Oddly, it works fine for me
Ah, it looks like some links open to this tab Contiene
and mess up the script.
This script would run much faster if you only checked links that show Biblioteca Elsa Morante
in the Lo Trovi In
list on the results page.
I noticed that the script works much better with Firefox. Searching for "Stephen King" and filtering by RMBO2
I get 4 pages, and only 4 records without iframe, not perferct but very near, congrats Mike!!!
I noticed that the script works much better with Firefox. Searching for "Stephen King" and filtering by RMBO2 I get 4 pages, and only 4 records without iframe, not perferct but very near, congrats Mike!!!
It may never work 100% of the time due to the fact it's loading every result in an iframe, but I'm sure the code can be tweaked a bit. One problem is the linked pages aren't consistent in how they display information. I think one bug happens when there is only one Lo Trovi In
. There are others too that can be accounted for, given enough code.
Yes, the major bug seems to be when there's only one library inLo Trovi in
. It would be great if you could find a way to get over it! Thanks again!
Do you really need this info for every result, or only a few? It may be a lot faster to create a button to click to load the info for only the results you need, vs loading every link into an iframe
Yes, generally I need this info for almost every result (except the records with contiene
tab), as I need to compare them through a panoramic view. As to the other method, if I understood I would need to click 15 records per page before displaying the related tabs, is that right? Maybe if I see an example I I would better realize. Thank you again, Mike!
This seems to give the best results so far.
// ==UserScript==
// @name bibliotechediroma
// @namespace http://tampermonkey.net/
// @version 0.2
// @description try to take over the world!
// @author You
// @match https://www.bibliotechediroma.it/opac/query/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=bibliotechediroma.it
// @grant none
// ==/UserScript==
// https://www.bibliotechediroma.it/opac/query/stephen%20king?context=tmatm
(function() {
'use strict';
let url = window.location.href;
const main = async() => {
await new Promise(r => setTimeout(r, 500));
if ( window != top ) return;
let links = [...document.querySelectorAll(".titololistarisultati a[href][title]")];
let startIndex = (() => {
let el = document.querySelector(".list-document > LI");
if ( ! el ) return -999999;
let id = el.id;
if ( !id ) return -999999;
let num = id.match(/listadocumenti_(\d+)/)[1];
return parseInt(num);
})();
for ( let i=0;i<links.length;i++ ) {
try {
let link = links[i];
let index = i + startIndex;
let id = `#listadocumenti_${index}`;
let li = document.querySelector(id);
let container = document.createElement('div');
container.style = 'margin-left:16px';
container.innerText = " [ loading ] ";
container.onclick = () => { f.src = f.src }
li.appendChild(container);
let f = document.createElement('iframe');
f.style.display = 'none';
document.body.appendChild(f);
f.onload = async () => {
if ( f.src === null ) return;
try {
await new Promise(r => setInterval(() => {
if ( f.contentWindow.document.getElementById("tabDocument_item_tabloca") )
r();
}, 100));
f.contentWindow.document.getElementById("tabDocument_item_tabloca").click();
await new Promise(r => setTimeout(r, 100));
let morante = f.contentWindow.document.querySelector('#biblioteche [onclick*="Morante"]');
if ( morante ) morante.click();
await new Promise(r => setInterval(() => {
if ( f.contentWindow.document.querySelector('.inventario') )
r();
}, 100));
let tab = f.contentWindow.document.querySelector('.inventario');
let content = tab.outerHTML;
li.appendChild(tab);
container.parentNode.removeChild(container);
} catch (error) {
container.innerText = " [ failed ] ";
console.log(error)
}
f.src = null;
}
f.onerror = () => {
container.innerText = " [ failed ] ";
f.src = null;
}
f.src = link.href;
} catch (error) {
console.log(error);
}
await new Promise(r => setTimeout(r, 100));
}
}
main();
setInterval(() => {
if ( window.location.href !== url ) {
//console.log('href change');
url = window.location.href;
main();
}
}, 1000);
})();
Thanks Mike, the results are better but seem slower than the other script (on Chrome too)... Thanks again!
Hi Mike, I installed TamperMonkey extension on Android (I tried both Kiwi Browser and Firefox Nightly). I can't get the script working , should I set something in Tampermonkey Settings? Thanks!
The last script I posted works for me in Firefox Nightly on Android. I haven't checked Kiwi
(edit) Kiwi worked fine too
Sorry, Mike, it works indeed with both browsers (better on Kiwi), maybe I did some pasting error, thank you!
Hi Mike, I'm trying to use your extension with this template URL:
https://www.bibliotechediroma.it/opac/query/%s?context=tmatm
(where %s is to be replacede by the search key, for example Stephen King). I would like all the 15 resulting titles/records to be automatically opened after my search, so to have quickly the detailed records. Could you help me if possible (I guess with a Post-Search Script)? Thanks very much!