Skip to content

Instantly share code, notes, and snippets.

@isnot
Last active March 28, 2019 04:05
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save isnot/23d9087e6177cff88d0a39210a576e02 to your computer and use it in GitHub Desktop.
Save isnot/23d9087e6177cff88d0a39210a576e02 to your computer and use it in GitHub Desktop.
To Extract Google Plus Communities Members List
// ==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);
})();
@isnot
Copy link
Author

isnot commented Jun 12, 2018

使い方

  1. このUserScriptをインストールする
  2. G+のコミュニティを開く(例: Emacs - Google+
  3. ページを再読込する(下記のボタンが見えている場合は不要)
  4. 「getMembers」ボタンが現れるので、押す
  5. 最後までデータを取り込み終わると、テキストリンク「Download TSV」が現れる。クリックでダウンロードできる

@isnot
Copy link
Author

isnot commented Mar 27, 2019

更新しました

  • @Version 0.3
  • 結果出力は、直接ファイルをダウンロードするようにしました
  • コンソールを開く必要がなくなりました
  • メンバーの中に無効なアカウントが存在した場合に停止していた問題を修正。単に無視するようにしました

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment