如何在window.load事件后抓取网页翻译后的内容?Flask开发求助
问题解决:抓取Google翻译动态生成的内容
核心原因
你遇到的问题本质是:fetch 获取到的是原始HTML代码,而Google翻译的内容是通过客户端JavaScript动态修改DOM生成的。DOMParser 解析HTML时不会执行页面中的脚本,所以无法触发Google翻译的逻辑,自然拿不到翻译后的内容。
解决方案
方案1:直接调用Google翻译API(推荐)
放弃依赖前端的Google翻译元素,后端直接调用官方翻译API获取结果,这样更可靠且效率更高。
修改 app.py,添加翻译逻辑(需先申请Google Cloud翻译API密钥):
from flask import Flask, render_template, request import requests app = Flask(__name__) app.config["TEMPLATES_AUTO_RELOAD"] = True # 替换为你的Google Cloud翻译API密钥 GOOGLE_TRANSLATE_API_KEY = "your-api-key-here" TRANSLATE_API_URL = "https://translation.googleapis.com/language/translate/v2" @app.route("/") def index(): return render_template("gettranslation.html") @app.route("/translate") def translate(): word = request.args.get("word") source_lang = request.args.get("lang") target_lang = "en" # 调用翻译API response = requests.post(TRANSLATE_API_URL, params={ "key": GOOGLE_TRANSLATE_API_KEY }, json={ "q": word, "source": source_lang, "target": target_lang }) translation = response.json()["data"]["translations"][0]["translatedText"] return render_template("translate.html", translation=translation, word=word)
修改 translate.html 直接显示翻译结果:
<p>原文: {{word}}</p> <p>翻译: {{translation}}</p>
修改 gettranslation.html 直接请求翻译结果:
<script> async function translate(sourcelang, destlang, word){ const url = `/translate?word=${encodeURIComponent(word)}&lang=${sourcelang}`; const response = await fetch(url); const text = await response.text(); const parser = new DOMParser(); const htmlDoc = parser.parseFromString(text, 'text/html'); const translation = htmlDoc.querySelector('p:nth-child(2)').innerHTML; console.log(translation); } translate("fr", "en", "bonjour"); </script>
方案2:使用无头浏览器抓取动态内容
如果必须依赖前端的Google翻译元素,需要用无头浏览器模拟真实浏览器加载页面,等待翻译完成后再提取内容。这里以Playwright为例:
- 安装依赖:
pip install playwright playwright install chromium
- 修改
app.py新增专门的抓取接口:
from flask import Flask, render_template, request from playwright.sync_api import sync_playwright app = Flask(__name__) app.config["TEMPLATES_AUTO_RELOAD"] = True @app.route("/") def index(): return render_template("gettranslation.html") @app.route("/translate") def translate(): word = request.args.get("word") lang = request.args.get("lang") return render_template("translate.html", lang=lang, word=word) @app.route("/get-translation") def get_translation(): word = request.args.get("word") source_lang = request.args.get("lang") target_lang = "en" url = f"http://localhost:5000/translate?word={word}&lang={source_lang}#googtrans({source_lang}|{target_lang})" with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page() page.goto(url) # 等待翻译完成,通过检测内容变化判断 page.wait_for_function( "document.getElementById('to-translate').innerText !== arguments[0]", word ) translation = page.locator("#to-translate").inner_text() browser.close() return translation
修改 gettranslation.html 请求新接口:
<script> async function translate(sourcelang, destlang, word){ const url = `/get-translation?word=${encodeURIComponent(word)}&lang=${sourcelang}`; const response = await fetch(url); const translation = await response.text(); console.log(translation); } translate("fr", "en", "bonjour"); </script>
方案3:修正前端代码错误(仅修复页面显示)
你当前的 translate.html 存在语法错误,修正后页面翻译会正常,但无法解决fetch抓取动态内容的本质问题:
<script src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script> <div id="google_translate_element"></div> <p id="to-translate">{{word}}</p> <script> var lang = "{{ lang }}"; lang = lang.slice(0, 2); console.log(lang); function googleTranslateElementInit() { new google.translate.TranslateElement( { pageLanguage: lang, includedLanguages: 'en', autoDisplay: false }, "google_translate_element" ); // 手动触发翻译 setTimeout(() => { const combo = document.querySelector('.goog-te-combo'); if (combo) { combo.value = 'en'; combo.dispatchEvent(new Event('change')); } }, 1000); } // 修正锚点设置 window.location.href += `#googtrans(${lang}|en)`; </script>
总结
- 优先选择方案1,直接调用API稳定性和效率最优;
- 方案2适合必须依赖前端翻译逻辑的场景,但需要额外的无头浏览器依赖;
- 方案3仅能修复页面显示问题,无法解决
fetch抓取动态内容的核心矛盾。
内容的提问来源于stack exchange,提问作者msuf
相关产品推荐
相关产品推荐

