├── .gitattributes ├── LICENSE ├── README.md ├── gbppd-mini.js └── gbppd.js /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Mark 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JavaScript Google Books Preview Pages Downloader (GBPPD) 2 | 3 | GBPPD downloads Google Books Preview pages automatically. 4 | 5 | How to use: 6 | 7 | - Once you are on the start page of the book you are previewing, **"right click the preview page and choose Inspect" to open Chrome's JavaScript console. This is an important step to get into the iframe context.** 8 | - Copy the GBPPD JavaScript code (*the minified version is much easier to cut-and-paste*) and paste it on the console, then press ENTER. 9 | - Start GBPPD by typing on the console **gbppd.start()**, then press ENTER. 10 | - It will start scrolling automatically the pages and each time a page loads the GBPPD will capture it. 11 | - After reaching the last page, type **gbppd.finish()** on the console, then press ENTER. 12 | - GBPPD will open a new tab with a list of all the links of the preview pages and then download them all automatically. 13 | 14 | Watch video here: 15 | 16 | Old: https://youtu.be/cCFtlXJPoJ0 17 | New: https://youtu.be/LsbGFLBiPWQ 18 | -------------------------------------------------------------------------------- /gbppd-mini.js: -------------------------------------------------------------------------------- 1 | var gbppd = (function () { 2 | let e = document.getElementById("viewport"), 3 | t = null, 4 | n = [], 5 | o = [], 6 | l = document.getElementsByClassName("overflow-scrolling"), 7 | r = l ? l[0].scrollHeight : 0, 8 | i = 0, 9 | c = null, 10 | a = function (e, t) { 11 | for (let t of e) 12 | if ( 13 | "childList" == t.type && 14 | ((o = t.target.getElementsByTagName("img")), o) 15 | ) 16 | for (let e of o) n.push(e.src); 17 | }, 18 | u = function () { 19 | (i += Math.floor(751 * Math.random()) + 50), 20 | i < r ? l[0].scrollBy(0, 800) : clearInterval(c); 21 | }; 22 | return { 23 | start: function () { 24 | (t = new MutationObserver(a)), 25 | t.observe(e, { attributes: !0, childList: !0, subtree: !0 }), 26 | (c = setInterval(u, 500)); 27 | }, 28 | finish: function () { 29 | { 30 | let e = new Set(n), 31 | o = window.open(), 32 | l = 0; 33 | for (let t of e) 34 | o.document.write( 35 | '' + t + "
" 36 | ), 37 | (l += 1); 38 | !(function (e, t) { 39 | let n = null; 40 | !(function o(l) { 41 | if (l >= e.length) return n && clearTimeout(n), void t(); 42 | e[l].href.match(/books.google./) && e[l].click(), 43 | (n = setTimeout(function () { 44 | o(l + 1); 45 | }, 500)); 46 | })(0); 47 | })(o.document.getElementsByTagName("a"), () => { 48 | o.document.write("

FINISHED DOWNLOADING.

"); 49 | }), 50 | t && (t.disconnect(), (t = null)), 51 | clearInterval(c); 52 | } 53 | }, 54 | }; 55 | })(); 56 | -------------------------------------------------------------------------------- /gbppd.js: -------------------------------------------------------------------------------- 1 | var gbppd = (function () { 2 | let book = document.getElementById("viewport"); 3 | let observer = null; 4 | let links = []; 5 | let targets = []; 6 | 7 | let scroll = document.getElementsByClassName("overflow-scrolling"); 8 | let scrollHeight = scroll ? scroll[0].scrollHeight : 0; 9 | let scrollAmount = 800; 10 | let scrollCount = 0; 11 | let intervalId = null; 12 | 13 | let callback = function (mutationsList, observer) { 14 | for (let mutation of mutationsList) { 15 | if (mutation.type == "childList") { 16 | targets = mutation.target.getElementsByTagName("img"); 17 | 18 | if (targets) { 19 | for (let target of targets) { 20 | links.push(target.src); 21 | } 22 | } 23 | } 24 | } 25 | }; 26 | 27 | let movePage = function () { 28 | scrollCount += Math.floor(Math.random() * (scrollAmount - 50 + 1)) + 50; 29 | if (scrollCount < scrollHeight) { 30 | scroll[0].scrollBy(0, scrollAmount); 31 | } else { 32 | clearInterval(intervalId); 33 | } 34 | }; 35 | 36 | let downloadAllPages = function (a, callback) { 37 | let timeOutId = null; 38 | function next(i) { 39 | if (i >= a.length) { 40 | if (timeOutId) clearTimeout(timeOutId); 41 | callback(); 42 | return; 43 | } 44 | 45 | if (a[i].href.match(/books.google./)) { 46 | a[i].click(); 47 | } 48 | 49 | timeOutId = setTimeout(function () { 50 | next(i + 1); 51 | }, 500); 52 | } 53 | 54 | next(0); 55 | }; 56 | 57 | return { 58 | start: function () { 59 | observer = new MutationObserver(callback); 60 | observer.observe(book, { 61 | attributes: true, 62 | childList: true, 63 | subtree: true, 64 | }); 65 | intervalId = setInterval(movePage, 500); 66 | }, 67 | 68 | finish: function () { 69 | { 70 | let uniqLinks = new Set(links); 71 | let finishWindow = window.open(); 72 | 73 | let pageNum = 0; 74 | 75 | for (let link of uniqLinks) { 76 | finishWindow.document.write( 77 | '' + 83 | link + 84 | "" + 85 | "
" 86 | ); 87 | pageNum = pageNum + 1; 88 | } 89 | 90 | let anchors = finishWindow.document.getElementsByTagName("a"); 91 | 92 | downloadAllPages(anchors, () => { 93 | finishWindow.document.write("

FINISHED DOWNLOADING.

"); 94 | }); 95 | 96 | if (observer) { 97 | observer.disconnect(); 98 | observer = null; 99 | } 100 | 101 | clearInterval(intervalId); 102 | } 103 | }, 104 | }; 105 | })(); 106 | --------------------------------------------------------------------------------