const { Builder, By, until } = require('selenium-webdriver'); const fs = require('fs-extra'); const path = require('path'); const unzipper = require('unzipper'); const chrome = require('selenium-webdriver/chrome'); // 変数定義 const URL = 'https://andpad.jp/my/orders'; const LOGIN_ID = 'k.nogi@next-hd.co.jp'; const LOGIN_PASSWORD = 'Next79324$#'; let LOGFILE; // ORDER_NUMBER配列を定義 const ORDER_NUMBERS = [ '19103981', '19104345', '19104559', '19104708', '19104954', '19105947', '19106547', '19106952', '19361029', '19522309', '19657598', '19883159', '21384631', '21404611', '21486222', '21486225', '21558574', '22118169', '22247851', '22516280', '22838587', '23205190' ]; const BASE_FOLDER = 'E:\\デザイノANDPAD'; // Chrome default download folder let driver; async function main(orderNumber) { try { const options = new chrome.Options(); options.addArguments('--log-level=3'); // エラーのみ表示 options.addArguments('--disable-logging'); // Seleniumドライバ初期化 driver = await new Builder() .forBrowser('chrome') .setChromeOptions(options) .build(); // ログイン処理 await loginWithDriver(driver); // URLを開く const documentUrl = `${URL}/${orderNumber}/documents/folder`; await driver.get(documentUrl); // 件名を取得 const subject = await getSubject(); console.log('件名:', subject); // ログファイルを設定 LOGFILE = path.join(BASE_FOLDER, subject, '資料', 'ファイルリスト.txt'); // ドキュメントフォルダリストを取得 const folderElements = await driver.findElements(By.css('section.table-datalist')); console.log('フォルダ数:', folderElements.length); // driver.quit()はループ後に実行 // 各要素を処理 for (let element of folderElements) { const folderNameElement = await element.findElement(By.css('h3')); const folderName = await folderNameElement.getText(); try { const nullBox = await element.findElement(By.css('p.box-null')); console.log(`フォルダ "${folderName}" は空です。`); } catch (e) { // フォルダ構造を作成 const folderPath = path.join(BASE_FOLDER, subject, '資料', folderName); await fs.ensureDir(folderPath); console.log('フォルダ作成:', folderPath); LOGFILE && await fs.appendFile(LOGFILE, `\n${folderPath}\n`, 'utf8'); const downloadLinks = await element.findElements(By.css('a.btn-small')); const downloadButtons = []; for (let link of downloadLinks) { const text = await link.getText(); if (text === 'ダウンロード') { downloadButtons.push(link); } } // ドキュメントダウンロード処理 await documentDownload(folderPath, downloadButtons, orderNumber); } } //await driver.quit(); } catch (error) { console.error('エラー:', error); } // finally節でdriver.quit()を呼ばないことで、Chromeを自動終了させない } async function loginWithDriver(driver) { // Chromeウインドウを最大化 await driver.manage().window().maximize(); // ログイン画面へ遷移 await driver.get('https://andpad.jp/login'); // 「ログイン画面へ」ボタンをクリック try { const loginPageBtn = await driver.findElement(By.xpath('//input[@value="ログイン画面へ"]')); await loginPageBtn.click(); await driver.sleep(1000); } catch (e) { // ボタンがなければスキップ } // ログインIDとパスワード入力 const loginIdInput = await driver.findElement(By.id('email')); await loginIdInput.clear(); await loginIdInput.sendKeys(LOGIN_ID); const passwordInput = await driver.findElement(By.id('password')); await passwordInput.clear(); await passwordInput.sendKeys(LOGIN_PASSWORD); // ログインボタン押下 const loginButton = await driver.findElement(By.css('button[type="submit"]')); await loginButton.click(); // ログイン後のURLとタイトルを出力 await driver.sleep(1000); } async function getSubject() { const subjectElement = await driver.findElement(By.css('div.tooltip[data-toggle="order-name-tooltip"]')); const subject = await subjectElement.getText(); return subject; } async function documentDownload(folderPath, downloadButtons, orderNumber) { const tagUrl = `${URL}/${orderNumber}/documents/folder`; // Chrome Preferencesで自動ダウンロード設定 const chrome = require('selenium-webdriver/chrome'); const prefs = { 'download.default_directory': folderPath, 'download.prompt_for_download': false, 'safebrowsing.enabled': false, 'plugins.always_open_pdf_externally': true }; const options = new chrome.Options(); options.setUserPreferences(prefs); options.addArguments('--log-level=3'); // エラーのみ表示 options.addArguments('--disable-logging'); // Selenium起動(driver再起動) let subDriver = await new Builder() .forBrowser('chrome') .setChromeOptions(options) .build(); await loginWithDriver(subDriver); // 指定タグURLへ遷移 await subDriver.get(tagUrl); await subDriver.sleep(2000); for (let link of downloadButtons) { const href = await link.getAttribute('href'); const fileName = await link.getAttribute('download'); //console.log('ダウンロード開始:', fileName); await subDriver.get(href); // ファイルの存在チェック(最大30秒待機) const maxWaitTime = 30000; const startTime = Date.now(); let fileDownloaded = false; while (Date.now() - startTime < maxWaitTime) { if (await fileExists(path.join(folderPath, fileName))) { fileDownloaded = true; break; } await subDriver.sleep(100); } if (!fileDownloaded) { console.warn('警告: ファイルのダウンロードがタイムアウトしました:', fileName); } console.log('ダウンロード完了:', fileName); LOGFILE && await fs.appendFile(LOGFILE, ` - ${fileName}\n`, 'utf8'); await subDriver.sleep(1000); } // ブラウザを閉じる await subDriver.quit(); } async function fileExists(filePath) { try { await fs.access(filePath, fs.constants.F_OK); return true; } catch { return false; } } // 全ORDER_NUMBERを順次実行 (async () => { for (const orderNumber of ORDER_NUMBERS) { console.log(`\n===== ${orderNumber} の処理開始 =====`); await main(orderNumber); console.log(`===== ${orderNumber} の処理終了 =====\n`); } console.log('全ての処理が完了しました。'); })();