Last active
March 28, 2019 04:05
-
-
Save isnot/23d9087e6177cff88d0a39210a576e02 to your computer and use it in GitHub Desktop.
To Extract Google Plus Communities Members List
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name EGPCML | |
// @namespace https://plus.google.com/+いしだなおと | |
// @version 0.3 | |
// @description To Extract Google Plus Communities Members List | |
// @author isnot | |
// @match https://plus.google.com/communities/* | |
// @match https://plus.google.com/u/0/communities/* | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
// 最後まで読み込めたかな? | |
const checkBottom = function(bt) { | |
const pos = bt.snapshotLength - 1; | |
const t_node_content = bt.snapshotItem(pos).textContent || ''; | |
console.log(t_node_content); | |
return t_node_content.indexOf('未読はありません') !== -1; | |
}; | |
// 一人分の整形 | |
const formatNode = function(n) { | |
var line = []; | |
const a_node = document.evaluate('a', n, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); | |
const img = a_node.snapshotItem(0).firstChild.firstChild; | |
const n_node = document.evaluate('div[2]/div[1]/div', a_node.snapshotItem(0), null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); | |
// console.log([n, a_node.snapshotItem(0).href, img.src]); | |
line.push(n_node.snapshotItem(0).textContent); | |
line.push(a_node.snapshotItem(0).href); | |
line.push(img.src); | |
// TSV タブ区切りテキスト | |
return line.join('\t'); | |
}; | |
// 最終的に、全部を取り出すところ | |
const onComplete = function() { | |
var iterator = document.evaluate('//div[@role="list"]', document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); | |
var lastNode; | |
var thisNode; | |
var node1; | |
var text = ''; | |
try { | |
thisNode = iterator.iterateNext(); | |
// find last node | |
while (thisNode) { | |
lastNode = thisNode; | |
thisNode = iterator.iterateNext(); | |
} | |
if (!Object.hasOwnProperty.call(lastNode, 'firstChild')) { | |
// console.log(lastNode); | |
node1 = lastNode.firstChild; | |
text += formatNode(node1) + '\n'; | |
node1 = node1.nextSibling; | |
while (node1) { | |
text += formatNode(node1) + '\n'; | |
node1 = node1.nextSibling; | |
} | |
putDownloadButton(text); | |
} | |
} catch (e) { | |
console.log('Error: Document tree modified during iteraton. ' + e); | |
} | |
}; | |
const getMembers = function(e) { | |
// メンバーを開く | |
const m_node = document.evaluate('//div[@itemtype="http://schema.org/WebPage/Community"]/div', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); | |
m_node.snapshotItem(1).firstChild.click(); | |
// メンバーリストが開くのを待ち(1秒)、自動でスクロール(2秒おきに回す)して全部読み込む | |
setTimeout(function() { | |
const scroll = document.evaluate('//div[@role="heading"]', document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); | |
scroll.iterateNext();scroll.iterateNext();scroll.iterateNext(); | |
const tta = scroll.iterateNext().parentNode.parentNode.parentNode.parentNode.parentNode; | |
const inter = setInterval(function() { | |
tta.scrollTop = tta.scrollHeight; | |
// console.log([inter, tta.scrollTop, tta.scrollHeight]); | |
if (checkBottom(document.evaluate('//div[@role="heading"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null))) { | |
clearInterval(inter); | |
onComplete(); | |
} | |
}, 2000); | |
}, 1000); | |
}; | |
const putDownloadButton = function(content) { | |
const filename = 'download_' + new Date().toLocaleTimeString('en-GB') + '.tsv'; | |
const blob = new Blob([content], {'type': 'text/csv'}); | |
const url = window.URL || window.webkitURL; | |
const blob_url = url.createObjectURL(blob); | |
var dlink = document.createElement('a'); | |
dlink.href = blob_url; | |
dlink.download = filename; | |
dlink.textContent = 'Download TSV'; | |
document.getElementById('EGPCMLDBTN').appendChild(dlink); | |
}; | |
// 処理開始するボタンを設置 | |
const key_node = document.evaluate('//div[@itemtype="http://schema.org/WebPage/Community"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); | |
var alink = document.createElement('button'); | |
alink.addEventListener('click', getMembers, false); | |
alink.textContent = 'getMembers'; | |
const button_pos = key_node.snapshotItem(0); | |
button_pos.appendChild(alink); | |
button_pos.id = 'EGPCMLDBTN'; | |
// console.log(key_node.snapshotItem(0).textContent); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
更新しました