如何让Playwright以日语JIS编码读取下载的CSV文件
解决Playwright下载日语CSV乱码并入库的问题
通过Playwright自动下载日语CSV文件后,直接以UTF-8读取会导致日语字符乱码,进而造成数据库存储错误。由于需要全流程自动化,无法手动通过Excel转码,需通过代码实现Shift-JIS编码转UTF-8的处理。
核心思路
下载的CSV文件采用**Shift-JIS(Japanese JIS的常用衍生编码)**编码,需先将文件的二进制内容解码为UTF-8,再进行CSV解析和数据库入库操作。以下是完整实现步骤:
1. 完整代码实现
结合Playwright下载、转码、CSV解析与MySQL入库的代码示例:
const { test, expect } = require('@playwright/test'); const path = require('path'); const fs = require('fs'); const csv = require('csv-parser'); const mysql = require('mysql'); const iconv = require('iconv-lite'); const { Transform } = require('stream'); test('自动下载CSV并转码入库', async ({ page }) => { // 1. 设置下载路径并监听下载事件 const downloadPath = path.join(process.cwd(), 'csv'); await page.context().setDownloadBehavior({ path: downloadPath }); // 触发下载操作(替换为实际的下载按钮点击逻辑) await page.click('text="下载CSV"'); // 等待下载完成 const download = await page.waitForEvent('download'); const fileName = await download.suggestedFilename(); const csvPath = path.join(downloadPath, fileName); await download.saveAs(csvPath); // 2. 读取Shift-JIS编码的CSV并转码为UTF-8 const transcodeStream = iconv.decodeStream('shiftjis'); const results = []; // 流式处理CSV(大文件友好) fs.createReadStream(csvPath) .pipe(transcodeStream) .pipe(csv()) .on('data', (data) => results.push(data)) .on('end', async () => { // 3. 连接MySQL并插入数据 const connection = mysql.createConnection({ host: 'your-host', user: 'your-user', password: 'your-password', database: 'your-db', charset: 'utf8mb4' // 确保数据库支持日语字符 }); connection.connect(); // 批量插入示例(可根据实际表结构调整) const insertQuery = `INSERT INTO your_table ( 来店店舗, 来店日, 受付No., 来店に含む, 顧客No., 顧客名, 新規, 目的, メニューコード, メニュー, 数量, 金額, 割引, 計, 担当者, 指名, 区分, 売上区分, 消費税率, 役務購入日, 契約書No., 消化担当者2, フリーコード1, フリーコード2, フリーコード3, レジ担当, 契約時レジ担当, 未渡商品 ) VALUES ?`; const values = results.map(row => [ row['来店店舗'], row['来店日'], row['受付No.'], row['来店に含む'], row['顧客No.'], row['顧客名'], row['新規'], row['目的'], row['メニューコード'], row['メニュー'], row['数量'], row['金額'], row['割引'], row['計'], row['担当者'], row['指名'], row['区分'], row['売上区分'], row['消費税率'], row['役務購入日'], row['契約書No.'], row['消化担当者2'], row['フリーコード1'], row['フリーコード2'], row['フリーコード3'], row['レジ担当'], row['契約時レジ担当'], row['未渡商品'] ]); connection.query(insertQuery, [values], (error, results) => { if (error) throw error; console.log(`成功插入 ${results.affectedRows} 条数据`); connection.end(); }); }); });
2. 关键注意事项
- 编码确认:确保下载的CSV确实是Shift-JIS编码,若为其他JIS系列编码(如ISO-2022-JP),可将
iconv.decodeStream('shiftjis')替换为对应编码(如'iso-2022-jp')。 - 数据库字符集:MySQL需设置
utf8mb4字符集(支持完整Unicode,包含所有日语字符),避免入库后再次乱码。 - 流式处理:使用流式转码+解析适合大文件,避免内存溢出;若为小文件,也可使用同步读取方式(如你提供的测试代码)。
- Playwright下载设置:通过
setDownloadBehavior指定下载路径,确保能正确获取到下载的文件。
3. 测试转码有效性
若仅需验证转码是否正确,可使用你提供的测试代码,只需确保读取的是原始二进制文件,转码后即可得到正确日语内容:
const { test, expect } = require('@playwright/test'); const path = require('path'); const fs = require('fs'); const iconv = require('iconv-lite'); test('验证CSV转码', async ({ page }) => { const csvPath = path.join(process.cwd(), 'csv', `20240218.csv`); const contentBuffer = fs.readFileSync(csvPath); const utf8Content = iconv.decode(contentBuffer, 'shiftjis'); console.log(utf8Content); // 输出正确日语内容 });
内容的提问来源于stack exchange,提问作者Tung Le
相关产品推荐
相关产品推荐

