最新の記事に掲載されているYoutubeのURLをスクレイピングする
googleのcloud functionsを使用するので、導入は以下を参照
今回も、puppeteerを使用してクローリングします。
やりたいのは、Newspicksの "NewsPicks×J-WAVE"というユーザーの最新記事に掲載されるYoutubeのURLを得ることです。
今回は、iframeのURLを取得することができました。
const puppeteer = require('puppeteer');
let page;
async function getBrowserPage() {
// Launch headless Chrome. Turn off sandbox so Chrome can run under root.
const browser = await puppeteer.launch({ args: ['--no-sandbox'] });
return browser.newPage();
}
exports.getYoutube = async (req, res) => {
if (!page) {
page = await getBrowserPage();
}
await page.goto('https://newspicks.com/user/9455?ref=timeline_9455');
await await page.waitFor(10000)
await page.click('body > div.contents-container > div.page-content.wide > div.user-page > div.tab-contents > div.picks.tab-content.selected > div.items > div:nth-child(1) > a > div.title._ellipsised');
await await page.waitFor(10000)
await page.click('body > div.contents-container > div.page-content > div.news-summary > div > div.contents-area > div.news > div:nth-child(3) > a');
function wait (ms) {
return new Promise(resolve => setTimeout(() => resolve(), ms));
}
for (var i = 0; i < 15; i++) {
await page.evaluate(_ => {
window.scrollBy(0, window.innerHeight);
});
await wait(15);
}
const elems = await page.$('#body > div:nth-child(1) > div > div.np-embedded.youtube > iframe');
const jsHandle = await elems.getProperty('src');
const text = await jsHandle.jsonValue();
res.set('Content-Type', 'application/json');
res.send(text);
}
特に困ったのは、スクロールしないとページが表示されなかった部分。
for (var i = 0; i < 15; i++) {
await page.evaluate(_ => {
window.scrollBy(0, window.innerHeight);
});
await wait(15);
}
でスクロールします。
--------------------------------------------------------------------------------------
次に、セレクターを指定しても文字列が返ってこないため、
const elems = await page.$('#body > div:nth-child(1) > div > div.np-embedded.youtube > iframe');
const jsHandle = await elems.getProperty('src');
const text = await jsHandle.jsonValue();
という形でtextを指定しなければなりません。