Tự động dịch tài liệu với Google Translate

Photo by Edurne Tx on Unsplash

Trong bài viết này, mình sẽ trình bày cách sử dụng Puppeteer để tự động dịch tài liệu trên website Google Translate.

Giới thiệu

Trong tuần vừa rồi, mình cần phải dịch các file tài liệu docx từ tiếng Anh sang tiếng Việt. Nhờ Google Translate, mình chỉ cần upload file docx lên, nhấn nút dịch rồi tải về. Nhưng có quá nhiều file, chẳng lẽ phải ngồi upload từng file để dịch. Do đó mình quyết định tạo một script để tự động quy trình này.

Ý tưởng ban đầu của mình là dùng công cụ xdotool (một công cụ để tương tác trên X11 server của Linux) để điều khiển con trỏ tự click vào vị trí của các nút trên web. Nhưng cách này khá chuối vì mình phải delay một khoảng thời gian cố định để đợi file được dịch. Và các file có dung lượng khác nhau sẽ có thời gian delay khác nhau.

Do đó, mình chuyển sang dùng Puppeteer. Trong bài viết này, mình sẽ trình bày cách mình dùng puppeteer để tự động dịch một file tài liệu docx.

Chuẩn bị

  • Máy tính đã cài đặt NodeJS.
  • Trình soạn thảo code.
  • Tệp tài liệu docx.

Thực hiện

Khởi tạo dự án

Tạo một thư mục mới cho dự án, sau đó di chuyển vào thư mục này và khởi tạo dự án NodeJS.

mkdir automate-google-translate
cd automate-google-translate
npm init -y

Cài đặt Puppeteer

Sau đó, cài các package cần thiết cho dự án. Ngoài puppeteer, chúng ta cần cài đặt thêm puppeteer-extra-plugin-stealth để không bị chương trình anti-bot phát hiện. Nếu Google phát hiện chúng ta đang dùng puppeteer, tài liệu tải về sẽ không được dịch.

Cài đặt các package:

npm install puppeteer puppeteer-extra puppeteer-extra-plugin-stealth

Lập trình

Việc lập trình giống như lập trình để điều khiển thiết bị vậy, chúng ta sẽ lập trình để puppeteer thực hiện các hành động sau:

  • Mở trình duyệt.
  • Mở tab mới.
  • Mở url https://translate.google.com/?sl=en&tl=vi&op=docs.
  • Kiểm tra xem file docx có tồn tại không.
  • Upload file docx.
  • Nhấn nút “Translate”.
  • Nhấn nút “Download Translate”.
  • Đóng trình duyệt.

Import modules:

const puppeteer = require('puppeteer-extra')
const StealthPlugin = require('puppeteer-extra-plugin-stealth')
const fs = require('fs');

Hàm khởi tạo trình duyệt:

// init browser
async function initBrowser(puppeteer) {
 const options = {
   headless: false, // this help browser can download file
   slowMo: 200, // help google translate not skip button download
 };
 
 const browser = await puppeteer.launch(options);
 console.log('initialized browser');
 
 return browser;
}

Hàm để mở một trang web mới:

// load page
async function loadAPage(browser, url) {
 const page = await browser.newPage();
 await page.goto(url);
 console.log(`loaded page ${url}`);
 
 return page;
}

Hàm để kiểm tra xem một file có tồn tại không:

// check is file existed
function checkFileExisted(filePath) {
 try {
   stats = fs.statSync(filePath);
   return true;
 }
 catch (e) {
   console.log('File does not exist.');
   return false;
 }
}

Hàm để upload, dịch và tải file về máy:

// translate document
async function translateFile(page, filePath) {
 // upload file
 const elementHandle = await page.$("input[type=file]");
 await elementHandle.uploadFile(filePath);
 console.log('uploaded document');
 
 // translate
 await page.waitForXPath("//button[contains(., 'Translate')]");
 const [btnTranslate] = await page.$x("//button[contains(., 'Translate')]");
 if (btnTranslate) {
   await btnTranslate.click();
 }
 console.log('file translated');
 
 // download
 await page.waitForXPath("//button[contains(., 'Download translation')]");
 const [btnDownload] = await page.$x("//button[contains(., 'Download translation')]");
 if (btnDownload) {
   await btnDownload.click();
   console.log('download translated file');
 }
}

Cuối cùng, hoàn chỉnh chương trình:

// main
(async() => {
 const url = 'https://translate.google.com/?sl=en&tl=vi&op=docs';
 const filePath = './lipsum.docx';
 
 const browser = await initBrowser(puppeteer.use(StealthPlugin()));
 const page = browser ? await loadAPage(browser, url) : null;
 checkFileExisted(filePath) ? await translateFile(page, filePath) : null;
 
 // exit browser
 console.log('browser will be closed after 3s...');
 await page.waitForTimeout(3000);
 await browser.close();
})();

Demo

Xem thử kết quả như thế nào?

Source code

https://drive.google.com/file/d/1UC9oaWaoYu1NtDiOGdFBN3AOMtLgmS_z/view?usp=sharing

Kết

Cảm ơn các bạn đã xem bài viết. Hẹn gặp lại các bạn ở các bài viết sau.

Related posts

Quản lý nhiều phiên làm việc trong Linux

Hướng dẫn cấu hình headless Raspberry Pi

Tạo hình nền gradient bằng ImageMagick (tiếp theo)