-
Notifications
You must be signed in to change notification settings - Fork 0
/
infiniteScroll.js
115 lines (94 loc) · 3.53 KB
/
infiniteScroll.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
const MAXIMUM_NTRIALS = 5
const MINIMUM_SLEEP_MS = 500
const MAXIMUM_SLEEP_MS = 2000
const CLEAR_ID = "remove-filter193"
const FILTER_ID = "Filter193"
const PERSON_DATA_CLASS = "person__data__main"
function randomDuration(minimum, maximum) {
return Math.floor(Math.random() * maximum) + minimum
}
async function sleep(time) {
return new Promise(resolve => setTimeout(resolve, time))
}
async function randomSleep() {
return await sleep(randomDuration(MINIMUM_SLEEP_MS, MAXIMUM_SLEEP_MS))
}
// Source: http://bgrins.github.io/devtools-snippets/#console-save
(function(console) {
console.save = function(data, filename) {
if (!data) {
console.error("Console.save: No data")
return
}
if (!filename) {
filename = "console.json"
}
if (typeof data === "object") {
data = JSON.stringify(data, undefined, 4)
}
var blob = new Blob([data], {type: "text/json"}), a = document.createElement('a')
a.download = filename
a.href = window.URL.createObjectURL(blob)
a.setAttribute("download", filename)
a.dispatchEvent(new MouseEvent("click"))
}
})(console)
class InfiniteScroll {
constructor(department) {
console.log("Initializing infinite scroll...")
this.resetFilter()
this.simulateKeyboardEvent(FILTER_ID, department)
this.department = department
this.currentScrollHeight = 0
this.numberOfScrolls = 0
this.numberOfTrials = 0
}
async exhaust() {
if (this.numberOfTrials > MAXIMUM_NTRIALS) {
this.summarize()
return
}
this.currentScrollHeight = document.body.scrollHeight
window.scrollTo(0, this.currentScrollHeight)
await randomSleep()
if (this.currentScrollHeight === document.body.scrollHeight) {
const attemptsRemaining = MAXIMUM_NTRIALS - this.numberOfTrials
this.numberOfTrials++
let updateMessage = "Bottom of scroll window detected. Will check for additional content " + attemptsRemaining.toString() + " more time"
updateMessage += attemptsRemaining === 1 ? "..." : "s..."
console.log(updateMessage)
} else {
this.numberOfTrials = 0
this.numberOfScrolls++
console.log(`Scroll ${this.numberOfScrolls} was successful!`)
}
this.entriesRemain() ? await this.exhaust() : this.summarize()
}
summarize() {
console.log("We should be at the bottom of the infinite scroll now. Done!")
console.log(`Loaded ${this.numberOfScrolls} pages for ${this.department}.`)
console.save(document.documentElement.outerHTML, this.department + ".html")
}
entriesRemain() {
const elements = Array.prototype.slice.call(document.getElementsByClassName(PERSON_DATA_CLASS))
return elements.every(element => element.innerText.includes(this.department))
}
simulateKeyboardEvent(id, text) {
const input = document.getElementById(id)
input.value += text
input.dispatchEvent(new Event("input", { bubbles: true }))
}
resetFilter() {
window.scrollTo(0, 0)
document.getElementById(CLEAR_ID).click()
}
}
const departments = ["English", "Music", "History"]
for (let department of departments) {
const infiniteScroll = new InfiniteScroll(department)
try {
await infiniteScroll.exhaust()
} catch (error) {
console.log(`Scrolling for ${department} failed: ${error}`)
}
}