HTML版英语学习系统

HTML版英语学习系统

这是一个完全免费、无需安装、功能完整的英语学习工具,使用HTML + CSS +JavaScript实现。

功能

  1. 文本朗读练习 - 输入英文文章,系统朗读帮助练习听力和发音,适合跟读练习,模仿学习;
  2. 实时词典查询 - 双击任意英文单词即可查看释义、音标和发音,适合新词汇学习和发音;(这一点,使用 Free Dictionary API,要联网)
  3. 分段学习 - 可以选择朗读全文、选中段落或当前段落;
  4. 重复练习 - 支持1-3次重复或循环播放,强化记忆;
  5. 学生自学 - 适合学生课文预习和自学;

个性化设置

  1. 语音选择 - 可选择不同的英语发音(美音、英音等)
  2. 语速调节 - 从0.5到2倍速,适应不同学习阶段
  3. 音调控制 - 调整音调让发音更清晰
  4. 音量控制 - 根据环境调整合适音量

运行截图

双击单词情况如下:

源码如下:

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>英语学习系统 - 文本转语音与词典查询</title><style>body {font-family: Arial, sans-serif;max-width: 1000px;margin: 0 auto;padding: 20px;color: #333;background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);min-height: 100vh;}.container {background: rgba(255, 255, 255, 0.95);border-radius: 15px;padding: 30px;box-shadow: 0 20px 40px rgba(0,0,0,0.1);}h1 {color: #2c3e50;text-align: center;margin-bottom: 10px;font-size: 28px;}.subtitle {text-align: center;color: #666;margin-bottom: 30px;font-style: italic;}.controls {margin: 20px 0;background-color: #fff;padding: 25px;border-radius: 12px;box-shadow: 0 4px 15px rgba(0,0,0,0.08);}textarea {width: 100%;height: 220px;margin: 10px 0;padding: 20px;border: 2px solid #e0e0e0;border-radius: 8px;font-size: 18px;line-height: 1.6;resize: vertical;box-sizing: border-box;transition: border-color 0.3s;}textarea:focus {outline: none;border-color: #667eea;box-shadow: 0 0 10px rgba(102, 126, 234, 0.2);}.parameter {display: flex;align-items: center;margin: 20px 0;justify-content: flex-start;gap: 15px;}.parameter label {min-width: 90px;text-align: right;margin-right: 15px;color: #555;font-weight: 600;}select {padding: 10px;border: 2px solid #e0e0e0;border-radius: 6px;background-color: #fff;font-size: 14px;transition: border-color 0.3s;}select:focus {outline: none;border-color: #667eea;}#voiceSelect {width: 460px;}#playCount {width: 130px;}input[type="range"] {width: 300px;height: 8px;margin: 0 15px;-webkit-appearance: none;background: linear-gradient(to right, #667eea, #764ba2);border-radius: 4px;outline: none;}input[type="range"]::-webkit-slider-thumb {-webkit-appearance: none;width: 20px;height: 20px;background: #fff;border: 3px solid #667eea;border-radius: 50%;cursor: pointer;box-shadow: 0 2px 6px rgba(0,0,0,0.2);}.value-display {min-width: 40px;text-align: center;background: #f8f9fa;padding: 5px 10px;border-radius: 4px;font-weight: 600;color: #667eea;}.status-display {margin: 25px 0;padding: 15px 20px;background: linear-gradient(135deg, #667eea, #764ba2);color: white;border-radius: 8px;font-size: 15px;font-weight: 500;text-align: center;}.buttons-container {margin-top: 25px;display: flex;justify-content: center;gap: 15px;flex-wrap: wrap;}.special-buttons {margin-top: 20px;padding-top: 20px;border-top: 2px solid #f0f0f0;display: flex;justify-content: center;gap: 15px;flex-wrap: wrap;}button {padding: 12px 25px;border: none;border-radius: 8px;font-size: 15px;font-weight: 600;cursor: pointer;transition: all 0.3s;color: white;background: linear-gradient(135deg, #4CAF50, #45a049);box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3);}button:hover {transform: translateY(-2px);box-shadow: 0 6px 20px rgba(76, 175, 80, 0.4);}button:active {transform: translateY(0);}.special-button {background: linear-gradient(135deg, #2196F3, #1976D2);box-shadow: 0 4px 15px rgba(33, 150, 243, 0.3);}.special-button:hover {box-shadow: 0 6px 20px rgba(33, 150, 243, 0.4);}/* 词典查询相关样式 */.word-popup {position: absolute;background: white;border: 2px solid #667eea;border-radius: 12px;padding: 25px;max-width: 450px;box-shadow: 0 10px 30px rgba(0,0,0,0.2);z-index: 1000;font-size: 14px;animation: popupShow 0.3s ease;}@keyframes popupShow {from { opacity: 0; transform: scale(0.9) translateY(-10px); }to { opacity: 1; transform: scale(1) translateY(0); }}.word-popup .word-header {display: flex;align-items: baseline;gap: 15px;flex-wrap: wrap;margin-bottom: 20px;border-bottom: 2px solid #f0f0f0;padding-bottom: 15px;}.word-popup h3 {margin: 0;color: #667eea;font-size: 24px;font-weight: 700;}.word-popup .phonetic {color: #666;font-family: monospace;background: #f8f9fa;padding: 4px 8px;border-radius: 4px;}.word-popup .audio-btn {background: linear-gradient(135deg, #667eea, #764ba2);border: none;padding: 8px 15px;border-radius: 6px;cursor: pointer;color: white;font-size: 13px;margin-bottom: 15px;transition: all 0.3s;}.word-popup .audio-btn:hover {transform: translateY(-1px);box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);}.word-popup .meanings {max-height: 350px;overflow-y: auto;margin-bottom: 20px;}.word-popup .meaning-group {margin-bottom: 20px;background: #fafbfc;padding: 15px;border-radius: 8px;}.word-popup .part-of-speech {color: #667eea;font-weight: 700;margin-bottom: 10px;font-size: 16px;}.word-popup ol {margin: 0;padding-left: 25px;color: #333;}.word-popup ol li {margin: 10px 0;line-height: 1.5;}.word-popup .definition {color: #333;margin-bottom: 6px;}.word-popup .example {color: #666;font-style: italic;background: #e8f4fd;padding: 8px;border-left: 3px solid #667eea;margin-top: 8px;border-radius: 4px;}.word-popup .close-btn {width: 100%;margin-top: 20px;padding: 12px;background: linear-gradient(135deg, #95a5a6, #7f8c8d);border: none;border-radius: 6px;cursor: pointer;color: white;font-weight: 600;}.word-popup .close-btn:hover {background: linear-gradient(135deg, #7f8c8d, #6c7b7d);}.error-message {position: fixed;bottom: 30px;right: 30px;background: linear-gradient(135deg, #e74c3c, #c0392b);color: white;padding: 15px 25px;border-radius: 8px;animation: fadeIn 0.3s ease;box-shadow: 0 6px 20px rgba(231, 76, 60, 0.3);font-weight: 600;}@keyframes fadeIn {from { opacity: 0; transform: translateY(30px); }to { opacity: 1; transform: translateY(0); }}.learning-tip {background: linear-gradient(135deg, #f093fb, #f5576c);color: white;padding: 15px;border-radius: 8px;margin-bottom: 20px;<!-- text-align: center; -->font-weight: 500;}@media (max-width: 768px) {body {padding: 10px;}.container {padding: 20px;}.parameter {flex-direction: column;align-items: flex-start;}.parameter label {text-align: left;margin-bottom: 8px;}#voiceSelect {width: 100%;}input[type="range"] {width: 100%;margin: 10px 0;}.buttons-container,.special-buttons {flex-direction: column;align-items: center;}button {width: 200px;}}</style>
</head>
<body><div class="container"><h1>英语学习系统</h1><p class="subtitle">文本转语音 + 实时词典查询</p><div class="learning-tip">💡 (1)如果“开始朗读”不发音,请考虑选择语音是否不当。(2)可以设置播放次数,调整语速、音量和音调。(2)双击英文单词可查看英文释义、音标(这项功能需要联网,使用 Free Dictionary API实现)。</div><div class="controls"><label>你可以在下面文本区域输入文字,或者往其中粘贴复制的文本:</label><textarea id="textToSpeak" placeholder="请输入英文文本开始学习...">Welcome to the English Learning System!
This is an interactive text-to-speech application with dictionary lookup.
You can practice pronunciation, adjust speech parameters, and learn new vocabulary.
Double-click on any word like "pronunciation" or "vocabulary" to see its definition and hear how it sounds.</textarea><div class="parameter"><label for="voiceSelect">语音:</label><select id="voiceSelect"></select><label for="playCount">次数:</label><select id="playCount"><option value="1">播放1次</option><option value="2">播放2次</option><option value="3">播放3次</option><option value="-1">循环播放</option></select></div><div class="parameter"><label for="rate">语速:</label><input type="range" id="rate" min="0.5" max="2" step="0.1" value="1"><span id="rateValue" class="value-display">1.0</span><label for="pitch">音调:</label><input type="range" id="pitch" min="0.5" max="2" step="0.1" value="1"><span id="pitchValue" class="value-display">1.0</span></div><div class="parameter">            <label for="volume">音量:</label><input type="range" id="volume" min="0" max="1" step="0.1" value="1"><span id="volumeValue" class="value-display">1.0</span></div><div class="status-display" id="statusDisplay">系统就绪 - 开始你的英语学习之旅!</div><div class="buttons-container"><button onclick="speak()">🔊 开始朗读</button><button onclick="pause()">⏸️ 暂停</button><button onclick="resume()">▶️ 继续</button><button onclick="stop()">⏹️ 停止</button><button class="special-button" onclick="speakSelectedText()">📖 读选中文本</button><button class="special-button" onclick="speakCurrentParagraph()">📄 读当前段落</button></div></div></div><script>let speechSynth = window.speechSynthesis;let utterance = null;let currentVoice = null;let voices = [];let playCount = 1;let totalPlayCount = 1;// 加载语音列表function loadVoices() {voices = speechSynth.getVoices();let voiceSelect = document.getElementById('voiceSelect');// 对语音进行排序voices.sort((a, b) => {if (a.lang < b.lang) return -1;if (a.lang > b.lang) return 1;return a.name.localeCompare(b.name);});// 创建语言分组的对象let voicesByLang = {};voices.forEach(voice => {if (!voicesByLang[voice.lang]) {voicesByLang[voice.lang] = [];}voicesByLang[voice.lang].push(voice);});voiceSelect.innerHTML = '';// 遍历排序后的语言分组Object.keys(voicesByLang).sort().forEach(lang => {let groupElement = document.createElement('optgroup');groupElement.label = getLangLabel(lang);voicesByLang[lang].forEach((voice) => {let option = document.createElement('option');option.textContent = `${voice.name}`;option.setAttribute('data-voice-index', voices.indexOf(voice));if (currentVoice && voice.name === currentVoice.name) {option.selected = true;}groupElement.appendChild(option);});voiceSelect.appendChild(groupElement);});// 初始化当前语音if (!currentVoice && voices.length > 0) {currentVoice = voices[0];voiceSelect.selectedIndex = 0;}}// 添加双击事件监听document.getElementById('textToSpeak').addEventListener('dblclick', function(e) {const selectedText = window.getSelection().toString().trim();if (selectedText && /^[a-zA-Z]+$/.test(selectedText)) {lookupWord(selectedText);}});// 查询单词async function lookupWord(word) {updateStatus(`正在查询单词 "${word}"...`);try {const response = await fetch(`https://api.dictionaryapi.dev/api/v2/entries/en/${word}`);const data = await response.json();if (data && data.length > 0) {showWordDefinition(word, data[0]);updateStatus(`单词 "${word}" 查询成功!`);} else {showError('未找到该单词的释义');updateStatus('查询失败 - 未找到释义');}} catch (error) {showError('查询失败,请稍后重试');updateStatus('网络查询失败');}}// 显示单词释义function showWordDefinition(word, data) {let popup = document.createElement('div');popup.className = 'word-popup';// 构建释义内容let content = `<div class="word-header"><h3>${word}</h3>${data.phonetics && data.phonetics[0]?.text ? `<span class="phonetic">${data.phonetics[0].text}</span>` : ''}</div>`;// 添加发音按钮(如果有音频链接)const audioUrl = data.phonetics?.find(p => p.audio)?.audio;if (audioUrl) {content += `<button class="audio-btn" onclick="playAudio('${audioUrl}')">🔊 播放发音</button>`;}// 添加释义if (data.meanings && data.meanings.length > 0) {content += '<div class="meanings">';data.meanings.forEach(meaning => {content += `<div class="meaning-group"><div class="part-of-speech">${meaning.partOfSpeech}</div><ol>${meaning.definitions.map(def => `<li><div class="definition">${def.definition}</div>${def.example ? `<div class="example">Example: ${def.example}</div>` : ''}</li>`).join('')}</ol></div>`;});content += '</div>';}// 添加关闭按钮content += '<button class="close-btn" onclick="this.parentElement.remove()">关闭</button>';popup.innerHTML = content;document.body.appendChild(popup);// 定位弹出框const selection = window.getSelection();const range = selection.getRangeAt(0);const rect = range.getBoundingClientRect();// 调整弹出位置,确保在可视区域内let left = rect.left + window.scrollX;let top = rect.bottom + window.scrollY + 10;// 检查右边界if (left + 450 > window.innerWidth) {left = window.innerWidth - 470;}popup.style.left = `${left}px`;popup.style.top = `${top}px`;}// 播放音频function playAudio(url) {new Audio(url).play();}// 显示错误信息function showError(message) {const errorDiv = document.createElement('div');errorDiv.className = 'error-message';errorDiv.textContent = message;document.body.appendChild(errorDiv);setTimeout(() => errorDiv.remove(), 3000);}// 获取语言显示名称function getLangLabel(langCode) {const langNames = {'zh-CN': '中文 (中国)','zh-TW': '中文 (台湾)','zh-HK': '中文 (香港)','en-US': '英语 (美国)','en-GB': '英语 (英国)','ja-JP': '日语 (日本)','ko-KR': '韩语 (韩国)','fr-FR': '法语 (法国)','de-DE': '德语 (德国)','es-ES': '西班牙语 (西班牙)','it-IT': '意大利语 (意大利)','ru-RU': '俄语 (俄罗斯)',};return langNames[langCode] || langCode;}// 初始化语音if (speechSynth.onvoiceschanged !== undefined) {speechSynth.onvoiceschanged = loadVoices;}setTimeout(loadVoices, 100);// 监听播放次数选择变化document.getElementById('playCount').addEventListener('change', function(e) {totalPlayCount = parseInt(e.target.value);});// 语音选择改变事件document.getElementById('voiceSelect').addEventListener('change', function(e) {let selectedOption = e.target.options[e.target.selectedIndex];let voiceIndex = selectedOption.getAttribute('data-voice-index');currentVoice = voices[voiceIndex];});// 更新滑块值显示document.getElementById('rate').addEventListener('input', function(e) {document.getElementById('rateValue').textContent = parseFloat(e.target.value).toFixed(1);});document.getElementById('pitch').addEventListener('input', function(e) {document.getElementById('pitchValue').textContent = parseFloat(e.target.value).toFixed(1);});document.getElementById('volume').addEventListener('input', function(e) {document.getElementById('volumeValue').textContent = parseFloat(e.target.value).toFixed(1);});// 更新状态显示function updateStatus(message) {document.getElementById('statusDisplay').textContent = message;}// 创建并播放音频function createAndPlayUtterance(text) {if (!text.trim()) {updateStatus('没有文本可以朗读');return;}utterance = new SpeechSynthesisUtterance(text);if (currentVoice) {utterance.voice = currentVoice;}utterance.rate = parseFloat(document.getElementById('rate').value);utterance.pitch = parseFloat(document.getElementById('pitch').value);utterance.volume = parseFloat(document.getElementById('volume').value);utterance.onend = function(event) {console.log(`第 ${playCount} 次播放结束`);if (totalPlayCount === -1 || playCount < totalPlayCount) {playCount++;updateStatus(`正在播放第 ${playCount} 次...`);setTimeout(() => createAndPlayUtterance(text), 500);} else {updateStatus('播放完成 ✓');}};utterance.onstart = function() {updateStatus(`正在播放第 ${playCount} 次... 🔊`);};speechSynth.speak(utterance);}// 开始朗读function speak() {stop();let text = document.getElementById('textToSpeak').value;playCount = 1;totalPlayCount = parseInt(document.getElementById('playCount').value);createAndPlayUtterance(text);}// 获取选中的文本function getSelectedText() {const textarea = document.getElementById('textToSpeak');const start = textarea.selectionStart;const end = textarea.selectionEnd;if (start === end) {return '';}return textarea.value.substring(start, end);}// 获取光标所在段落的文本function getCurrentParagraph() {const textarea = document.getElementById('textToSpeak');const text = textarea.value;const cursorPosition = textarea.selectionStart;// 将文本按换行符分割const paragraphs = text.split('\n');let currentPosition = 0;for (let i = 0; i < paragraphs.length; i++) {const paragraphLength = paragraphs[i].length + 1; // +1 是为了计入换行符const paragraphEnd = currentPosition + paragraphLength;if (cursorPosition <= paragraphEnd) {return paragraphs[i].trim();}currentPosition = paragraphEnd;}return paragraphs[paragraphs.length - 1].trim();}// 朗读选中的文本function speakSelectedText() {stop();const selectedText = getSelectedText();if (!selectedText) {updateStatus('请先选中要朗读的文本');return;}playCount = 1;totalPlayCount = parseInt(document.getElementById('playCount').value);updateStatus('开始朗读选中文本...');createAndPlayUtterance(selectedText);}// 朗读光标所在段落function speakCurrentParagraph() {stop();const currentParagraph = getCurrentParagraph();if (!currentParagraph) {updateStatus('光标所在位置没有找到有效段落');return;}playCount = 1;totalPlayCount = parseInt(document.getElementById('playCount').value);updateStatus('开始朗读当前段落...');createAndPlayUtterance(currentParagraph);}// 暂停朗读function pause() {speechSynth.pause();updateStatus('已暂停 ⏸️');}// 继续朗读function resume() {speechSynth.resume();updateStatus('继续播放... ▶️');}// 停止朗读function stop() {speechSynth.cancel();playCount = totalPlayCount;updateStatus('已停止 ⏹️');}</script>
</body>
</html>

OK!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/86710.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JUC面试篇】Java并发编程高频八股——线程与多线程

目录 1. 什么是进程和线程&#xff1f;有什么区别和联系&#xff1f; 2. Java的线程和操作系统的线程有什么区别&#xff1f; 3. 线程的创建方式有哪些? 4. 如何启动和停止线程&#xff1f; 5. Java线程的状态模型&#xff08;有哪些状态&#xff09;&#xff1f; 6. 调用…

LSTM-SVM多变量时序预测(Matlab完整源码和数据)

LSTM-SVM多变量时序预测&#xff08;Matlab完整源码和数据&#xff09; 目录 LSTM-SVM多变量时序预测&#xff08;Matlab完整源码和数据&#xff09;效果一览基本介绍程序设计参考资料 效果一览 基本介绍 代码主要功能 该代码实现了一个LSTM-SVM多变量时序预测模型&#xff0c…

ES6——数组扩展之Set数组

在ES6&#xff08;ECMAScript 2015&#xff09;中&#xff0c;JavaScript的Set对象提供了一种存储任何值唯一性的方式&#xff0c;类似于数组但又不需要索引访问。这对于需要确保元素唯一性的场景非常有用。Set对象本身并不直接提供数组那样的方法来操作数据&#xff08;例如ma…

日志收集工具-logstash

提示&#xff1a;Windows 环境下 安装部署 logstash 采集日志文件 文章目录 一、下载二、解压部署三、常用插件四、常用配置 Logstash 服务器数据处理管道&#xff0c;能够从多个来源采集数据&#xff0c;转换数据&#xff0c;然后将数据发送到您最喜欢的存储库中。Logstash 没…

6个月Python学习计划 Day 21 - Python 学习前三周回顾总结

✅ 第一周&#xff1a;基础入门与流程控制&#xff08;Day 1 - 7&#xff09; “打地基”的一周&#xff0c;我们走完了从变量、输入输出、判断、循环到第一个小型系统的完整链路。 &#x1f4d8; 学习重点&#xff1a; Python 基础语法&#xff1a;变量类型、字符串格式化、注…

Spring Boot SQL数据库功能详解

Spring Boot自动配置与数据源管理 数据源自动配置机制 当在Spring Boot项目中添加数据库驱动依赖&#xff08;如org.postgresql:postgresql&#xff09;后&#xff0c;应用启动时自动配置系统会尝试创建DataSource实现。开发者只需提供基础连接信息&#xff1a; 数据库URL格…

java每日精进 6.11【消息队列】

1.内存级Spring_Event 1.1 控制器层&#xff1a;StringTextController /*** 字符串文本管理控制器* 提供通过消息队列异步获取文本信息的接口*/ RestController RequestMapping("/api/string-text") public class StringTextController {Resourceprivate StringTex…

【凌智视觉模块】rv1106 部署 ppocrv4 检测模型 rknn 推理

PP-OCRv4 文本框检测 1. 模型介绍 如有需要可以前往我们的仓库进行查看 凌智视觉模块 PP-OCRv4在PP-OCRv3的基础上进一步升级。整体的框架图保持了与PP-OCRv3相同的pipeline&#xff0c;针对检测模型和识别模型进行了数据、网络结构、训练策略等多个模块的优化。 从算法改…

uniapp Vue2 获取电量的独家方法:绕过官方插件限制

在使用 uniapp 进行跨平台应用开发时&#xff0c;获取设备电量信息是一个常见的需求。然而&#xff0c;uniapp 官方提供的uni.getBatteryInfo方法存在一定的局限性&#xff0c;它不仅需要下载插件&#xff0c;而且目前仅支持 Vue3&#xff0c;这让使用 Vue2 进行开发的开发者陷…

Go语言中的if else控制语句

if else是Go语言中最基础也最常用的条件控制语句&#xff0c;用于根据条件执行不同的代码块。下面我将详细介绍Go语言中if else的各种用法和特性。 1. 基本语法 1.1. 最简单的if语句 if 条件表达式 {// 条件为true时执行的代码 } 示例&#xff1a; if x > 10 {fmt.Prin…

[Spring]-AOP

AOP场景 AOP: Aspect Oriented Programming (面向切面编程) OOP: Object Oriented Programming (面向对象编程) 场景设计 设计: 编写一个计算器接口和实现类&#xff0c;提供加减乘除四则运算 需求: 在加减乘除运算的时候需要记录操作日志(运算前参数、运算后结果)实现方案:…

Web3 借贷与清算机制全解析:链上金融的运行逻辑

Web3 借贷与清算机制全解析&#xff1a;链上金融的运行逻辑 超额抵押借款 例如&#xff0c;借款人用ETH为抵押借入DAI&#xff1b;借款人的ETH的价值一定是要超过DAI的价值&#xff1b;借款人可以任意自由的使用自己借出的DAI 稳定币 第一步&#xff1a;借款人需要去提供一定…

RK3588开发笔记-GNSS-RTK模块调试

目录 前言 一、什么是GNSS/RTK 二、硬件连接 三、内核配置 四、模块调试 五、ntripclient使用 总结 前言 在RK3588平台上集成高精度定位功能是许多工业级应用的需求。本文记录了我调试GNSS-RTK模块的全过程,包含硬件连接、驱动移植、数据解析和精度优化等关键环节,希望对…

Vue.js $emit的介绍和简单使用

前言 在 Vue.js 开发中&#xff0c;组件化是核心思想之一。但组件间的通信是一个重要课题&#xff0c;特别是子组件向父组件传递数据的场景。Vue 提供了多种通信方式&#xff0c;而$emit正是实现子→父通信的关键方法。本文将深入解析$emit的原理、使用场景及最佳实践。 一、$e…

【Linux 学习计划】-- 简易版shell编写

目录 思路 创建自己的命令行 获取用户命令 分割命令 检查是否是内建命令 cd命令实现 进程程序替换执行程序 总代码 结语 思路 int main() {while (1){// 1. 自己的命令行PrintCommandLine();// 2. 获取用户命令char command[SIZE];int n GetUserCommand(command, si…

一个完整的日志收集方案:Elasticsearch + Logstash + Kibana+Filebeat (二)

&#x1f4c4; 本地 Windows 部署 Logstash 连接本地 Elasticsearch 指南 ✅ 目标 在本地 Windows 上安装并运行 Logstash配置 Logstash 将数据发送至本地 Elasticsearch测试数据采集与 ES 存储流程 &#x1f9f0; 前提条件 软件版本要求安装说明Java17Oracle JDK 下载 或 O…

Java使用Selenium反爬虫优化方案

当我们爬取大站的时候&#xff0c;就得需要对抗反爬虫机制的场景&#xff0c;因为项目要求使用Java和Selenium。Selenium通常用于模拟用户操作&#xff0c;但效率较低&#xff0c;所以需要我们结合其他技术来实现高效。 在 Java 中使用 Selenium 进行高效反爬虫对抗时&#xff…

状态管理方案对比与决策

1. 状态管理的基本概念 现代前端应用随着功能复杂度提升&#xff0c;状态管理已成为架构设计的核心挑战。状态管理本质上解决的是数据的存储、变更追踪和响应式更新问题&#xff0c;以确保UI与底层数据保持同步。 核心挑战: 状态共享与组件通信可预测的状态变更性能优化与重…

Fetch与Axios:区别、联系、优缺点及使用差异

Fetch与Axios&#xff1a;区别、联系、优缺点及使用差异 文章目录 Fetch与Axios&#xff1a;区别、联系、优缺点及使用差异一、联系二、区别1. 浏览器支持与兼容性2. 响应处理3. 请求拦截和响应拦截4. 错误处理 三、优缺点1. Fetch API优点缺点 2. Axios优点缺点 四、使用上的差…

【Docker】快速入门与项目部署实战

我们在部署一个项目时&#xff0c;会出现一系列问题比如&#xff1a; 命令太多了&#xff0c;记不住软件安装包名字复杂&#xff0c;不知道去哪里找安装和部署步骤复杂&#xff0c;容易出错 其实上述问题不仅仅是新手&#xff0c;即便是运维在安装、部署的时候一样会觉得麻烦…