Last active
July 14, 2018 07:41
-
-
Save kimihito/0609e5d1db4f73c289d9855743ca0acb to your computer and use it in GitHub Desktop.
puppeteerでゆうちょダイレクトから残高情報をスクレイピングする
This file contains hidden or 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
import Yucho from './yucho'; | |
const yuchoID = process.env.YUCHO_ID | |
const password = process.env.YUCHO_PASSWORD | |
const aikotoba = process.env.YUCHO_AIKOTOBA | |
(async () => { | |
const yucho = await new Yucho(yuchoID, password, aikotoba) | |
await yucho.run() | |
console.log(yucho.despositBalance) | |
})(); | |
process.on('exit', () => { | |
process.exit(0); | |
}); |
This file contains hidden or 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
import puppeteer from 'puppeteer'; | |
class Yucho { | |
constructor(id, password, aikotoba) { | |
this.browser = null | |
this.page = null | |
this.targetUrl = "https://direct.jp-bank.japanpost.jp/direct_login.html?link_id=ycDctLgn" | |
this.id = id | |
this.password = password | |
this.aikotoba = JSON.parse(aikotoba) | |
this.questions = Object.keys(this.aikotoba) | |
this.answers = Object.values(this.aikotoba) | |
this.depositBalance = null | |
} | |
async run() { | |
await this.setup() | |
await this.typeId() | |
let doneAikotoba = null | |
for (;;) { | |
doneAikotoba = await this.setAokitoba() | |
if(doneAikotoba) { | |
break | |
} | |
} | |
await this.setPassword() | |
await this.skipInfo() | |
await this.storeDepositBalance() | |
await this.close() | |
} | |
async setup() { | |
if (!this.browser) { | |
this.browser = await puppeteer.launch({ | |
args: [ | |
'--no-sandbox', | |
'--disable-setuid-sandbox' | |
] | |
}) | |
} | |
if (!this.page) { | |
this.page = await this.browser.newPage() | |
} | |
await this.page.goto(this.targetUrl, { timeout: 0, waitUntil: 'networkidle2' }) | |
} | |
async close() { | |
await this.browser.close() | |
this.browser = null | |
this.page = null | |
} | |
async screenshot(path) { | |
await this.page.screenshot({ | |
path: path, fullPage: true | |
}) | |
} | |
async textFrom(selector) { | |
const text = await this.page.$eval(selector, item => { | |
if(!item) return null | |
return item.innerText | |
}) | |
return text | |
} | |
async typeId() { | |
const idAttrs = this.id.split('-') | |
for (let id of idAttrs.keys()) { | |
await this.type(`input[name='okyakusamaBangou${id+1}']`, idAttrs[id]) | |
} | |
await this.click("input[name='U010103']") | |
} | |
async type(selector, value) { | |
await this.page.type(selector, value) | |
} | |
async click(selector) { | |
this.page.click(selector) | |
await this.waitPageLoaded() | |
} | |
async waitPageLoaded() { | |
await this.page.waitForNavigation({timeout: 6000, waitUntil: "domcontentloaded"}); | |
} | |
async setPassword() { | |
await this.type("input[type='password']", this.password) | |
await this.click("li.btnBa.submit > input[type='button']") | |
} | |
async setAokitoba() { | |
const pageTitle = await this.textFrom('#strMain > h1') | |
if(!pageTitle) { | |
return true | |
} | |
if(!this.isAikotobaPage(pageTitle)) { | |
return true | |
} | |
const aikotobaQuestion = await this.textFrom('tr.req dd') | |
const answer = this.findAnswer(aikotobaQuestion) | |
await this.page.evaluate((text) => { | |
document.getElementsByName('aikotoba')[0].value = text | |
}, answer) | |
await this.click("li.btnBa:not(.back) > a") | |
return false | |
} | |
findAnswer(key) { | |
const index = this.questions.findIndex(q => { | |
return key.match(q) != null | |
}) | |
return this.answers[index] | |
} | |
async skipInfo() { | |
await this.click("p.btnBa.alignR.submit > a") | |
} | |
async storeDepositBalance() { | |
this.depositBalance = await this.textFrom('p.txtBalanceTy01.alignR') | |
} | |
isAikotobaPage(text) { | |
return text.match(/合言葉入力/) != null | |
} | |
} | |
export default Yucho |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment