This commit is contained in:
kyuuseiryuu 2026-03-21 14:43:51 +09:00
parent abec190d1d
commit fe97b67d87
7 changed files with 42 additions and 30 deletions

1
.gitignore vendored
View File

@ -34,3 +34,4 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
.DS_Store .DS_Store
user_data/ user_data/
debug-html/

View File

@ -2,7 +2,9 @@ import { fetch } from 'bun';
import BandaiCookie from './Cookie'; import BandaiCookie from './Cookie';
import { loginBandai } from './utils/account-utils'; import { loginBandai } from './utils/account-utils';
import * as cheerio from 'cheerio'; import * as cheerio from 'cheerio';
import { getBandaiCookieRedisKey, redis } from './utils'; import { getBandaiRawCookieRedisKey, redis } from './utils';
import fs from 'fs';
import path from 'path';
export default class Bandai { export default class Bandai {
#email: string; #email: string;
@ -38,7 +40,7 @@ export default class Bandai {
} }
async #isLogind() { async #isLogind() {
const hasCookie = await redis.get(getBandaiCookieRedisKey(this.#email)); const hasCookie = await redis.get(getBandaiRawCookieRedisKey(this.#email));
if (!hasCookie) return false; if (!hasCookie) return false;
const hasLoginId = await this.#fetch('https://p-bandai.jp/mypage') const hasLoginId = await this.#fetch('https://p-bandai.jp/mypage')
.then(res => res.text()) .then(res => res.text())
@ -46,11 +48,23 @@ export default class Bandai {
return !hasLoginId; return !hasLoginId;
} }
#debugHTML(html: string, name: string) {
const dir = path.resolve(__dirname, '../debug-html', this.#email.replace(/\W/g, '_'));
const file = path.resolve(dir, `${name}.html`);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(file, html);
}
async #getId() { async #getId() {
const selector = 'body > div.pb24-wrap > div.pb24-mypage-content > div.pb24-mypage-content__side > div:nth-child(1) > dl > dd:nth-child(2)'; const selector = '#headerMenu .pb24-header-menu__data--name > dd';
const id = await this.#fetch('https://p-bandai.jp/mypage/') const id = await this.#fetch('https://p-bandai.jp/mypage/')
.then(res => res.text()) .then(res => res.text())
.then(html => cheerio.load(html)) .then(html => {
this.#debugHTML(html, 'my-page');
return cheerio.load(html);
})
.then($ => { .then($ => {
return $(selector).text().trim(); return $(selector).text().trim();
}); });

View File

@ -1,7 +1,8 @@
import { getBandaiCookieRedisKey, redis } from "./utils"; import type { Cookie } from "puppeteer";
import { getBandaiRawCookieRedisKey, redis } from "./utils";
export default class BandaiCookie { export default class BandaiCookie {
#cookieMap = new Map<string, string>(); #cookieMap = new Map<string, Cookie>();
#id: string; #id: string;
@ -10,23 +11,21 @@ export default class BandaiCookie {
} }
async init() { async init() {
const cache = await redis.get(getBandaiCookieRedisKey(this.#id)); const cache = await redis.get(getBandaiRawCookieRedisKey(this.#id));
if (!cache) return; if (!cache) return;
cache.split(';').forEach((cookie) => { const cookies: Cookie[] = JSON.parse(cache);
const [key, value] = cookie.trim().split('='); cookies.map(cookie => {
if (!key || !value) return; this.#cookieMap.set(cookie.name, cookie);
this.#cookieMap.set(key, value);
}); });
console.debug('Cookie initialized.'); console.debug('Cookie initialized.');
} }
updateCookie(headers: Headers) { updateCookie(headers: Headers) {
const cookies = headers.getSetCookie(); const cookies = headers.getSetCookie();
const newCookies = cookies.map(cookie => (cookie.split(';')[0] ?? '').trim()).filter(Boolean); cookies.forEach(cookie => {
newCookies.forEach(cookie => { const cookieData = cookie.split(';'); // Extract the name=value part of
const [key, value] = cookie.trim().split('='); console.debug(cookieData);
if (!key || !value) return; // this.#cookieMap.set(cookie)
this.#cookieMap.set(key.trim(), value.trim());
}); });
} }
@ -38,7 +37,7 @@ export default class BandaiCookie {
} }
async saveCookie() { async saveCookie() {
const cookieString = this.getCookie(); const cookieString = JSON.stringify(this.#cookieMap.values().toArray());
await redis.set(getBandaiCookieRedisKey(this.#id), cookieString); await redis.set(getBandaiRawCookieRedisKey(this.#id), cookieString);
} }
} }

View File

@ -1,4 +1,4 @@
import { getBandaiCookieRedisKey, redis } from "."; import { getBandaiRawCookieRedisKey, redis } from ".";
import { initBrowser } from "./puppeteer-utils"; import { initBrowser } from "./puppeteer-utils";
export async function loginBandai(emai: string, password: string) { export async function loginBandai(emai: string, password: string) {
@ -20,12 +20,8 @@ export async function loginBandai(emai: string, password: string) {
page.click('#btnLogin'), page.click('#btnLogin'),
page.waitForNavigation(), page.waitForNavigation(),
]); ]);
const cookies = await browser.cookies() const rawCookies = await browser.cookies();
.then(cookies => { await redis.set(getBandaiRawCookieRedisKey(emai), JSON.stringify(rawCookies));
return cookies.map(cookie => `${cookie.name}=${cookie.value}`).join('; ');
});
console.debug('Cookie', cookies);
await redis.set(getBandaiCookieRedisKey(emai), cookies);
await browser.close() await browser.close()
return cookies; return;
} }

View File

@ -15,6 +15,7 @@ export const puppeteerInitArgs = [
export const CHROME = { export const CHROME = {
Windows: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', Windows: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
Linux: '/usr/bin/google-chrome', // Linux: '/usr/bin/google-chrome',
Linux: '/usr/bin/chromium',
Mac: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', Mac: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
}; };

View File

@ -3,7 +3,8 @@ import { RedisClient } from "bun";
import { CHROME } from "./constants"; import { CHROME } from "./constants";
export const redis = new RedisClient(process.env.REDIS); export const redis = new RedisClient(process.env.REDIS);
export const getBandaiCookieRedisKey = (email: string) => `bandai:cookies:${email}`; export const getBandaiRawCookieRedisKey = (email: string) => `bandai:cookies:${email}:raw`;
export const getChromePath = () => { export const getChromePath = () => {
const platform = process.platform; const platform = process.platform;
if (platform === 'win32') return CHROME.Windows; if (platform === 'win32') return CHROME.Windows;

View File

@ -1,12 +1,12 @@
import { test, expect } from "bun:test"; import { test, expect } from "bun:test";
import Bandai from "../src/Bandai"; import Bandai from "../src/Bandai";
import { getBandaiCookieRedisKey, redis } from "../src/utils"; import { getBandaiRawCookieRedisKey, redis } from "../src/utils";
test('Test login', async () => { test('Test login', async () => {
const email = 'allin-603@outlook.com'; const email = 'allin-603@outlook.com';
const password = '123456789qw'; const password = '123456789qw';
const account = new Bandai(email, password); const account = new Bandai(email, password);
await account.login(); await account.login();
const cookie = await redis.get(getBandaiCookieRedisKey(email)); const cookie = await redis.get(getBandaiRawCookieRedisKey(email));
expect(cookie).toBeDefined(); expect(cookie).toBeDefined();
}); });