Created
December 31, 2019 04:40
-
-
Save 59t9/4244463dd836d0fa5c322b622c8325e7 to your computer and use it in GitHub Desktop.
高解像度降水ナウキャストの画像取得 by puppeteer/node.js
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
const puppeteer = require('puppeteer'); | |
const fs = require('fs'); | |
require('date-utils'); | |
async function xpathClicker(page, xpath) { | |
await page.waitForXPath(xpath); | |
const elementHandleList = await page.$x(xpath); | |
await elementHandleList[0].click(); | |
await page.waitFor(1000); | |
} | |
(async () => { | |
const now = new Date(); | |
let dateTemp = new Date(); | |
dateTemp.setHours(now.getHours()-1); | |
const saveTimeOntheClock = new Date(dateTemp.getFullYear(), dateTemp.getMonth(), dateTemp.getDate(), dateTemp.getHours()); | |
const browser = await puppeteer.launch({headless: true, 'defaultViewport' : { 'width' : 1048, 'height' : 2000 }}); | |
console.log(saveTimeOntheClock.toFormat('YYYY/MM/DD HH24:MI:SS')); | |
try{ | |
const page = await browser.newPage(); | |
await page._client.send('Page.setDownloadBehavior', { | |
behavior : 'allow', | |
downloadPath: fs.realpathSync('./') | |
}); | |
await page.goto('https://www.jma.go.jp/jp/highresorad/#geolocationPageload=false', {waitUntil: "domcontentloaded"}); | |
// await page.screenshot({path: 'jma000.png'}); | |
// 念のためのズームアウト | |
for(let i=0; i<10; i++){ | |
const xpath = '//div[starts-with(@id,"control_jmamesh_highresorad")]/li[6]/span'; | |
await xpathClicker(page, xpath); | |
} | |
// await page.screenshot({path: 'jma001.png'}); | |
// ズームイン | |
for(let i=0; i<4; i++){ | |
const xpath = '//div[starts-with(@id,"control_jmamesh_highresorad")]/li[5]/span'; | |
await xpathClicker(page, xpath); | |
} | |
// await page.screenshot({path: 'jma002.png'}); | |
// ツールボタンを押して詳細を開く | |
{ | |
const xpath = '//div[starts-with(@id,"viewbutton_OTHER_jmamesh_highresorad")]'; | |
await xpathClicker(page, xpath); | |
} | |
// await page.screenshot({path: 'jma003.png'}); | |
// 指定の緯度 | |
{ | |
const xpath = '//input[starts-with(@id,"textLat_jmamesh_highresorad")]'; | |
await page.waitForXPath(xpath); | |
const elementHandleList = await page.$x(xpath); | |
await elementHandleList[0].focus(); | |
await page.keyboard.down('Control'); | |
await page.keyboard.press('A'); | |
await page.keyboard.up('Control'); | |
await page.keyboard.press('Backspace'); | |
await elementHandleList[0].type('34.968994'); | |
await page.waitFor(2000); | |
} | |
// await page.screenshot({path: 'jma004.png'}); | |
// 指定の経度 | |
{ | |
const xpath = '//input[starts-with(@id,"textLon_jmamesh_highresorad")]'; | |
await page.waitForXPath(xpath); | |
const elementHandleList = await page.$x(xpath); | |
await elementHandleList[0].focus(); | |
await page.keyboard.down('Control'); | |
await page.keyboard.press('A'); | |
await page.keyboard.up('Control'); | |
await page.keyboard.press('Backspace'); | |
await elementHandleList[0].type('135.102539'); | |
await page.waitFor(2000); | |
} | |
// await page.screenshot({path: 'jma005.png'}); | |
// 指定緯度経度への移動 | |
{ | |
const xpath = '//button[starts-with(@id,"mvCenter_jmamesh_highresorad")]'; | |
await xpathClicker(page, xpath); | |
} | |
// await page.screenshot({path: 'jma006.png'}); | |
// 設定保存ボタン | |
{ | |
const xpath = '//button[starts-with(@id,"svCenter_jmamesh_highresorad")]'; | |
await xpathClicker(page, xpath); | |
} | |
// await page.screenshot({path: 'jma007.png'}); | |
// 確認ダイアログ「はい」 | |
{ | |
const xpath = '//div[starts-with(@aria-describedby,"saveConfirmDialog")]//button[text()="はい"]'; | |
await xpathClicker(page, xpath); | |
} | |
// await page.screenshot({path: 'jma008.png'}); | |
// 設定展開ボタン | |
{ | |
const xpath = '//button[starts-with(@id,"mvsvCenter_jmamesh_highresorad")]'; | |
await xpathClicker(page, xpath); | |
} | |
// await page.screenshot({path: 'jma009.png'}); | |
// 確認ダイアログ「はい」 | |
{ | |
const xpath = '//div[starts-with(@aria-describedby,"moveConfirmDialog")]//button[text()="はい"]'; | |
await xpathClicker(page, xpath); | |
} | |
// await page.screenshot({path: 'jma010.png'}); | |
// ツールボタンを押して詳細を閉じる | |
{ | |
const xpath = '//div[starts-with(@id,"viewbutton_OTHER_jmamesh_highresorad")]'; | |
await xpathClicker(page, xpath); | |
} | |
// await page.screenshot({path: 'jma011.png'}); | |
// 最新時刻への更新 | |
{ | |
const xpath = '//input[@id="refresh-button"]'; | |
await xpathClicker(page, xpath); | |
} | |
// await page.screenshot({path: 'jma012.png'}); | |
// セーブしたい時刻(X時55分)への移動 | |
while (true) { | |
const xpath = '//*[@id="pinSvgText"]'; | |
await page.waitForXPath(xpath); | |
const elementHandleList = await page.$x(xpath); | |
let value = await (await elementHandleList[0].getProperty('textContent')).jsonValue(); | |
console.log(value); | |
let clock = value.split(':'); | |
let hour = saveTimeOntheClock.getHours(); | |
// await page.screenshot({path: 'jma013_' + clock[0] + clock[1] + '.png'}); | |
if (clock[0] == hour && clock[1] == '55') { | |
break; | |
} | |
// 5分過去へ | |
{ | |
const xpath = '//input[starts-with(@id,"viewtime_prev_jmamesh_highresorad")]'; | |
await xpathClicker(page, xpath); | |
} | |
} | |
// X時(5*i)分の画像取得 | |
for(let i=0; i<60/5; i++){ | |
let clock = []; | |
{ | |
const xpath = '//*[@id="pinSvgText"]'; | |
await page.waitForXPath(xpath); | |
const elementHandleList = await page.$x(xpath); | |
const value = await (await elementHandleList[0].getProperty('textContent')).jsonValue(); | |
console.log(value); | |
clock = value.split(':'); | |
} | |
// 画像保存 | |
{ | |
const xpath = '//input[starts-with(@id,"imagesave_jmamesh_highresorad")]'; | |
await xpathClicker(page, xpath); | |
} | |
// 保存先へ移動 | |
const srcfile = fs.realpathSync('./') + '/' + 'highresorad_' + saveTimeOntheClock.toFormat('YYYYMMDD') + clock[0] + clock[1] + '.png'; | |
const dstdir = fs.realpathSync('./') + '/' + saveTimeOntheClock.toFormat('YYYY/MM/DD'); | |
const dstfile = dstdir + '/' + saveTimeOntheClock.toFormat('YYYYMMDD') + '_' + clock[0] + clock[1] + '.png'; | |
console.log(srcfile); | |
fs.mkdirSync(dstdir, { recursive: true }); | |
fs.renameSync(srcfile, dstfile); | |
// 5分過去へ | |
{ | |
const xpath = '//input[starts-with(@id,"viewtime_prev_jmamesh_highresorad")]'; | |
await xpathClicker(page, xpath); | |
} | |
// await page.screenshot({path: 'jma013_' + clock[0] + clock[1] + '.png'}); | |
} | |
} catch(e) { | |
console.log(e.message); | |
} finally { | |
await browser.close(); | |
} | |
})(); |
OSを更新したついでにnode.jsやpuppeteerを更新しましたら、puppeteerではtypescript対応に関連してwaitFor()が廃止になるとの告知を知りました。waitForTimeOut()に差し替えると良いそうです。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
リアルタイムレーダーの時から使っているwatir - selenium - ChromeDriverのスクレーパーが高解像度降水ナウキャストでは動かなくなり、冬季休暇を機にpuppeteer/node.jsで書き直しました。日付処理の辺りはmoment.jsが今様らしいのですが、js慣らしで五里霧中ということでお見逃しください。