
facebookページのフィードを取得しよう!(難あり)
一般的な、facebookページのフィードの取得は、facebookのgraphAPIでデータを取得することが可能であり。以下の記事が参考になる。
だが、facebookのページフィードをFacebookGraphAPI経由で扱うには結構厄介な条件がある。
As of April 30, 2018, the
source
field for/page/feed
and/page/posts
will no longer be returned for Page-owned videos unless the User making the request has a role on the owning Page.公式レファレンスhttps://developers.facebook.com/docs/graph-api/reference/v3.2/page/feed
要するにだ・・・権限を持っていないfacebookフィードにはアクセスできないということである。
- 取得するfacebookページを保有していることor権限があること
- App申請およびレビューが通っていること
2018年4月30日以降、セキュリティ面が強化されており、今後も取得はさせてくれないと思われる。
FacebookPageのfeedにアクセスするのは、ちょっと難ありといえます。
仕方ないので、facebookのwebスクレイピングを行い必要な情報を集める必要があります。
facebookページのWebスクレイピングをしよう!
前述したように、Api経由でのfeed取得は諦める必要が出てくる。その場合は、ウェブスクレイピングをする方法しかなくなる。最近はgoogleがchromeのgui無しの動作ができるheadlessChromeを出してくれている。最近のwebスクレイピングは、これ一択である(少し重い)
Facebookページは、Javascriptを多用しているので、HeadlessChrome必須である。
その他ヘッドレスブラウザには下記があるようだ。
ヘッドレスブラウザの種類
ヘッドレスブラウザ
実装 名前 実行時間(s) 総評 chrome Headles Chrome 1.5〜2.5 今から使うならこれ。開発リソースの安心感 Electoron Nightmare 1.5〜2.5 Headles Chromeと大差はない。無理して乗り換える必要はない 独自実装 PhantomJS 4.3〜4.8 性能と開発リソースに難あり。使い続けるのは厳しい
nodejs: headlessChormeをインストール
基本的には、puppeteerをインストールすると自動的にインストールされる。
https://www.npmjs.com/package/puppeteer
GitHub - puppeteer/puppeteer: Node.js API for ChromeNode.js API for Chrome . Contribute to puppeteer/puppeteer development by creating an account on GitHub.
npm install puppeteer
実際にインストールすると、結構依存しているライブラリが多いようで色々と追加でインストールが必要だった。
facebookのページをスクレイピングするにはスクロールが必要。
facebookのページに関してスクレイピングをかける時には、無限スクロールが存在しているので、スクロールの機能を入れないと欲しいデータが取得できない。
具体的なやり方は、下記のサイトを参考にするのが良い。

とても簡潔なソースなので、改造もしやすくとてもいいw中の要素の個数指定もできるのが素晴らしい。
実際にfacebookページにあるアイテム10個が出現するまでスクロールしてhtmlを出力するソースは下記。nodejs完全なソースではないが,クラスの「._6ks」を10個取り出すまで、スクロールする感じ。
今回改造したソースの抜粋
[highlight_javascript]
function extractItems() {
const extractedElements = document.querySelectorAll(‘._6ks’);
const items = [];
for (let element of extractedElements) {
var u = String(element.innerHTML);
items.push(u);
}
return items;
}
async function scrapeInfiniteScrollItems(
page,
extractItems,
itemTargetCount,
scrollDelay = 1000,
) {
let items = [];
try {
let previousHeight;
while (items.length < itemTargetCount) {
items = await page.evaluate(extractItems);
previousHeight = await page.evaluate(‘document.body.scrollHeight’);
await page.evaluate(‘window.scrollTo(0, document.body.scrollHeight)’);
await page.waitForFunction(`document.body.scrollHeight > ${previousHeight}`);
await page.waitFor(scrollDelay);
}
} catch(e) { }
return items;
}
const getfbp = async(url,res)=>{
const browser = await puppeteer.launch({
headless: true,
args: [‘–no-sandbox’, ‘–disable-setuid-sandbox’],
});
const page = await browser.newPage();
page.setViewport({ width: 1280, height: 926 });
await page.goto(url);
const items = await scrapeInfiniteScrollItems(page, extractItems, 10);
let bodyHTML = await page.evaluate(() => document.body.innerHTML);
res.send(bodyHTML);
await browser.close();
};
[/highlight_javascript]
おそらく、重要になる部分は
ランチ時のオプション設定
args: [‘–no-sandbox’, ‘–disable-setuid-sandbox’],
facebookページのエレメント指定部分
const extractedElements = document.querySelectorAll(‘._6ks’);
以上。