Skip to content

Instantly share code, notes, and snippets.

@kimihito
Last active July 14, 2018 07:41
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 kimihito/0609e5d1db4f73c289d9855743ca0acb to your computer and use it in GitHub Desktop.
Save kimihito/0609e5d1db4f73c289d9855743ca0acb to your computer and use it in GitHub Desktop.
puppeteerでゆうちょダイレクトから残高情報をスクレイピングする
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);
});
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