質問編集履歴

1

追加

2022/01/21 12:58

投稿

keraker
keraker

スコア46

test CHANGED
File without changes
test CHANGED
@@ -11,3 +11,293 @@
11
11
  もとがブックマークレットなのでjavascriptを変換したときに何か失われてしまう部分でもあるのでしょうか。
12
12
 
13
13
  よろしくお願いします。
14
+
15
+ 実行した文は長いですが以下です。
16
+ ```ruby
17
+ scr=<<-eos
18
+ ((document, Promise, setTimeout, html, on, size, text) => {
19
+ const $ = (query, doc = document) => doc.querySelector(query)
20
+
21
+ const $$ = (query, doc = document) => doc.querySelectorAll(query)
22
+
23
+ const appendChild = (child, parent = document.body) => parent.appendChild(child)
24
+
25
+ const createElement = tag => document.createElement(tag)
26
+
27
+ const cleanup = () => {
28
+ if (iframe !== undefined) {
29
+ iframe.remove()
30
+ }
31
+ }
32
+
33
+ const concat = (base, append, more = []) => base.concat(append).concat(more)
34
+
35
+ const convert = row => `"${row.map(s => replaceArr(
36
+ s && typeof s !== 'string' && text in s
37
+ ? s[text]
38
+ : s,
39
+ [/"/g, /\n/g],
40
+ ['""', '']
41
+ )).join('","')}"`
42
+
43
+ const decode = href => {
44
+ let out = href
45
+
46
+ try {
47
+ out = decodeURI(href)
48
+ } catch (e) {}
49
+
50
+ return out
51
+ }
52
+
53
+ const download = () => {
54
+ const blob = new Blob([
55
+ new Uint8Array([0xEF, 0xBB, 0xBF]),
56
+ joinLines(concat([
57
+ convert([
58
+ 'href',
59
+ 'decoded',
60
+ 'title',
61
+ 'breadcrumb',
62
+ 'date',
63
+ 'description'
64
+ ])
65
+ ], ret))
66
+ ], {
67
+ type: 'text/csv'
68
+ })
69
+
70
+ const a = createElement('a')
71
+ const url = URL.createObjectURL(blob)
72
+
73
+ a.download = document.title + '.csv'
74
+ a.href = url
75
+
76
+ a.click()
77
+
78
+ setTimeout(() => URL.revokeObjectURL(url), 1000)
79
+ }
80
+
81
+ const filter = array => array.filter(item => !!item)
82
+
83
+ const joinLines = array => array.join('\n')
84
+
85
+ const last = (() => {
86
+ const g = $$('#rso .g')
87
+
88
+ if (g[size] === 0) {
89
+ return $('#rso')
90
+ } else {
91
+ return g[g[size] - 1].parentNode
92
+ }
93
+ })()
94
+
95
+ const main = async () => {
96
+ const found = scan()
97
+
98
+ if (found[size] === 0) {
99
+ alert('No item found.\nIf you think this script works incorrectly contact the creator.\nThx in advance.')
100
+ return
101
+ }
102
+
103
+ const message = [
104
+ `Found: ${found[size]}`,
105
+ `Total: ${found[size] + ret[size]}`
106
+ ]
107
+
108
+ ret = concat(ret, found)
109
+
110
+ await scroll()
111
+
112
+ const pnnext = $('#pnnext', doc)
113
+
114
+ if (pnnext === null) {
115
+ alert(joinLines(message))
116
+
117
+ cleanup()
118
+
119
+ return download()
120
+ }
121
+
122
+ message.unshift('Continue next page?')
123
+
124
+ if (confirm(joinLines(message))) {
125
+ await next(pnnext.href)
126
+
127
+ main()
128
+ } else {
129
+ cleanup()
130
+ download()
131
+ }
132
+ }
133
+
134
+ const mapElements = (query, callback) => Array.from($$(query, doc)).map(callback)
135
+
136
+ const next = href => {
137
+ if (iframe === undefined) {
138
+ iframe = createElement('iframe')
139
+
140
+ setStyle(iframe, {
141
+ display: 'none'
142
+ })
143
+
144
+ appendChild(iframe)
145
+ }
146
+
147
+ const progress = createElement('div')
148
+
149
+ setStyle(progress, {
150
+ background: 'black',
151
+ color: 'white',
152
+ left: 0,
153
+ padding: '8px 20px',
154
+ position: 'fixed',
155
+ top: 0,
156
+ zIndex: 1000
157
+ })
158
+
159
+ progress[text] = 'Loading...'
160
+
161
+ appendChild(progress)
162
+
163
+ return new Promise(resolve => {
164
+ iframe[on]('load', () => {
165
+ doc = iframe.contentWindow.document
166
+ progress.remove()
167
+
168
+ const wrapper = createElement('div')
169
+ wrapper[html] = $('#rso', doc)[html]
170
+ appendChild(wrapper, last)
171
+
172
+ if (doc !== document) {
173
+ $('#xjs')[html] = $('#xjs', doc)[html]
174
+ }
175
+
176
+ resolve()
177
+ }, {
178
+ once: true
179
+ })
180
+
181
+ iframe.src = href
182
+ })
183
+ }
184
+
185
+ const replace = (string, from, to = '') => (string || '').replace(from, to)
186
+ const replaceArr = (string, from, to) => from.reduce((prev, pattern, index) => replace(prev, pattern, to[index]), string)
187
+
188
+ const scan = () => filter(concat(
189
+ // All tab
190
+ mapElements('#rso div.g > div', item => {
191
+ const a = $('div.yuRUbf a', item)
192
+ if (!a || item === snippet) {
193
+ return false
194
+ }
195
+
196
+ const href = a.href
197
+ let date
198
+ let desc
199
+
200
+ if ($('#media_result_group', item)) {
201
+ desc = $('[role="heading"] span.hgKElc', item)
202
+ } else if ($('div.IsZvec g-img', item)) {
203
+ date = $('div.IsZvec div.fG8Fp', item).firstChild.wholeText
204
+ desc = $('div.IsZvec span.aCOpRe', item)
205
+ } else {
206
+ date = $('div.IsZvec span.wuQ4Ob', item)
207
+ desc = $('div.IsZvec div.VwiC3b', item)
208
+ }
209
+
210
+ return convert([
211
+ href,
212
+ decode(href),
213
+ $('div.yuRUbf h3', item),
214
+ $('div.yuRUbf cite', item),
215
+ typeof date === 'string'
216
+ ? date
217
+ : date && date.children[size] === 0 ? replace(date[text], / . ?$/) : '',
218
+ desc
219
+ ? (
220
+ date
221
+ ? replace(desc[text], date[text]).trimLeft()
222
+ : desc[text]
223
+ )
224
+ : ''
225
+ ])
226
+ }),
227
+
228
+ // News tab
229
+ mapElements('#rso g-card > div > div > a.WlydOe', item => {
230
+ const href = item.href
231
+
232
+ return convert([
233
+ href,
234
+ decode(href),
235
+ $('[role=heading]', item),
236
+ $('div.CEMjEf span', item),
237
+ $('p.S1FAPd span', item),
238
+ $('div.GI74Re', item)
239
+ ])
240
+ }),
241
+
242
+ // Images tab
243
+ mapElements('#islrg div.isv-r', item => {
244
+ const link = $('a[rel="noopener"]', item)
245
+ if (link === null) {
246
+ console.log(item)
247
+ return false
248
+ }
249
+ const href = link.href
250
+ const src = $('img', item).src
251
+
252
+ return convert([
253
+ href,
254
+ decode(href),
255
+ link.title,
256
+ $('div.fxgdke', link),
257
+ $('span.gRqDMe', item),
258
+ src.startsWith('data:') ? '' : src
259
+ ])
260
+ })
261
+ ))
262
+
263
+ const scroll = () => {
264
+ return new Promise(resolve => {
265
+ ($('#islmp') || document.body).scrollIntoView({
266
+ behavior: 'smooth',
267
+ block: 'end'
268
+ })
269
+
270
+ const listener = () => {
271
+ clearTimeout(timer)
272
+ timer = setTimeout(() => {
273
+ document.removeEventListener('scroll', listener)
274
+ resolve()
275
+ }, 500)
276
+ }
277
+ let timer
278
+
279
+ document[on]('scroll', listener, {
280
+ passive: true
281
+ })
282
+ listener()
283
+ })
284
+ }
285
+
286
+ const setStyle = (target, style) => {
287
+ for (let key in style) {
288
+ target.style[key] = style[key]
289
+ }
290
+ }
291
+
292
+ const snippet = $('#rso div.g > div div.g > div')
293
+
294
+ let doc = document
295
+ let iframe
296
+ let ret = []
297
+
298
+ main()
299
+ })(document, Promise, setTimeout, 'innerHTML', 'addEventListener', 'length', 'innerText')
300
+ eos
301
+
302
+ driver.execute_script(scr)
303
+ ```