Skip to content

Instantly share code, notes, and snippets.

@59t9
Created December 31, 2019 04:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 59t9/4244463dd836d0fa5c322b622c8325e7 to your computer and use it in GitHub Desktop.
Save 59t9/4244463dd836d0fa5c322b622c8325e7 to your computer and use it in GitHub Desktop.
高解像度降水ナウキャストの画像取得 by puppeteer/node.js
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();
}
})();
@59t9
Copy link
Author

59t9 commented Dec 31, 2019

リアルタイムレーダーの時から使っているwatir - selenium - ChromeDriverのスクレーパーが高解像度降水ナウキャストでは動かなくなり、冬季休暇を機にpuppeteer/node.jsで書き直しました。日付処理の辺りはmoment.jsが今様らしいのですが、js慣らしで五里霧中ということでお見逃しください。

@59t9
Copy link
Author

59t9 commented Dec 5, 2020

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