puppeteerというのを使ってみました。google chromeをコマンドラインから使えるやつです。久しぶりにjQueryやってる感じで、イライラした笑 でも便利そうだし、面白かった。これを使うと、なんか色々できそうで面白い。
本家マニュアルも読んだけど、この記事ありがたかったです。結構ややこしい。。。
サンプル
Googleの地図で新潟の焼肉屋を調べて、ランキング順に焼肉屋の情報を取得する
実行結果
コード
const puppeteer = require('puppeteer') const mapUrl = 'https://www.google.co.jp/maps/search/' const keywords = '新潟+焼肉' const containerEl = '[data-result-index]' const nameEl = 'h3 span' const countEl = 'span.section-result-num-ratings' const urlEl = 'button[data-section-id="ap"]' const backBtnEl = 'button.section-back-to-list-button' const main = async () => { const browser = await puppeteer.launch() const page = await browser.newPage() await page.goto(mapUrl + keywords) const shops = await getShops(page) console.log(shops) await browser.close() } const getShops = async (page) => { await page.waitFor(containerEl, {timeout: 10000}) const divLength = (await page.$$(containerEl)).length let shops = [] let rank = 1 for (let i = 0; i < divLength; i++) { const divs = await page.$$(containerEl) const shop = await getShop(page, divs[i], rank) if (shop) { shops.push(shop) rank++ } } return shops } const getShop = async (page, div, rank) => { const name = await div.$eval(nameEl, name => name.innerText) const reviewCount = await div.$eval(countEl, count => count.innerText) console.log(name) const url = await getUrl(page, div) return { rank: rank, name: name, reviewCount: reviewCount.replace(/\((\d+?)\)/, '$1'), url: url } } const getUrl = async (page, div) => { div.click() await page.waitFor(backBtnEl, {timeout: 10000}) const url = await page.$eval(urlEl, el => el.getAttribute('data-url') ).catch(() => null) console.log(url) page.click(backBtnEl) await page.waitFor(containerEl, {timeout: 10000}) return url } main()