diff --git a/app/static/config.yml b/app/static/config.yml index 173bc6b..7e681fe 100644 --- a/app/static/config.yml +++ b/app/static/config.yml @@ -2,7 +2,7 @@ css: item: - ../static/css/bootstrap.css - + - ../static/css/highlighted.css # 全局引入的js文件地址 js: head: # 在页面加载之前加载 diff --git a/app/static/css/highlighted.css b/app/static/css/highlighted.css new file mode 100644 index 0000000..167f595 --- /dev/null +++ b/app/static/css/highlighted.css @@ -0,0 +1,5 @@ + +.highlighted { + color: red; + font-weight: normal; +} \ No newline at end of file diff --git a/app/static/js/fillword.js b/app/static/js/fillword.js index b3a8b42..18461f0 100644 --- a/app/static/js/fillword.js +++ b/app/static/js/fillword.js @@ -1,5 +1,6 @@ -let isRead = true; -let isChoose = true; +// initialize from localStorage +let isRead = localStorage.getItem('readChecked') !== 'false'; // default to true +let isChoose = localStorage.getItem('chooseChecked') !== 'false'; function getWord() { return window.getSelection ? window.getSelection() : document.selection.createRange().text; @@ -11,6 +12,7 @@ function fillInWord() { if (!isChoose) return; const element = document.getElementById("selected-words"); element.value = element.value + " " + word; + localStorage.setItem('selectedWords', element.value); } document.getElementById("text-content").addEventListener("click", fillInWord, false); @@ -24,13 +26,15 @@ inputSlider.oninput = () => { function onReadClick() { isRead = !isRead; + localStorage.setItem('readChecked', isRead); } function onChooseClick() { isChoose = !isChoose; + localStorage.setItem('chooseChecked', isChoose); } // 如果网页刷新,停止播放声音 if (performance.getEntriesByType("navigation")[0].type == "reload") { Reader.stopRead(); -} \ No newline at end of file +} diff --git a/app/static/js/highlight.js b/app/static/js/highlight.js index 76b4793..c9c3a02 100644 --- a/app/static/js/highlight.js +++ b/app/static/js/highlight.js @@ -1,4 +1,4 @@ -let isHighlight = true; +let isHighlight = localStorage.getItem('highlightChecked') !== 'false'; // default to true function cancelBtnHandler() { cancelHighlighting(); @@ -39,15 +39,16 @@ function highLight() { } totalSet = new Set([...totalSet, ...matches]); } - } + } // 删除所有的mark标签,防止标签发生嵌套 articleContent = articleContent.replace(/<(mark)[^>]*>/gi, ""); articleContent = articleContent.replace(/<(\/mark)[^>]*>/gi, ""); - // 将文章中所有出现该单词word的地方改为:"<mark>" + word + "<mark>"。 + // 将文章中所有出现该单词word的地方改为:"<span class='highlighted'>" + word + "</span>"。 for (let word of totalSet) { - articleContent = articleContent.replace(new RegExp("\\b" + word + "\\b", "g"), "<mark>" + word + "</mark>"); + articleContent = articleContent.replace(new RegExp("\\b" + word + "\\b", "g"), "<span class='highlighted'>" + word + "</span>"); } document.getElementById("article").innerHTML = articleContent; + } function cancelHighlighting() { @@ -73,6 +74,7 @@ function toggleHighlighting() { isHighlight = true; highLight(); } + localStorage.setItem('highlightChecked', isHighlight); } showBtnHandler(); \ No newline at end of file diff --git a/app/templates/login.html b/app/templates/login.html index b8eb118..b0806b6 100644 --- a/app/templates/login.html +++ b/app/templates/login.html @@ -15,6 +15,10 @@ alert('输入不能为空!'); return false; } + if (password.includes(' ')) { + alert('输入不能包含空格!'); + return false; + } $.post( "/login", {'username': username, 'password': password}, function (response) { diff --git a/app/templates/mainpage_get.html b/app/templates/mainpage_get.html index e96e8dc..3ba0ece 100644 --- a/app/templates/mainpage_get.html +++ b/app/templates/mainpage_get.html @@ -34,9 +34,9 @@ <div class="alert alert-success" role="alert">共有文章 <span class="badge bg-success"> {{ number_of_essays }} </span> 篇</div> <p>粘贴1篇文章 (English only)</p> <form method="post" action="/"> - <textarea name="content" rows="10" cols="120"></textarea><br/> + <textarea name="content" id="article" rows="10" cols="120"></textarea><br/> <input type="submit" value="get文章中的词频"/> - <input type="reset" value="清除"/> + <input type="reset" value="清除" onclick="clearArticle()"/> </form> {% if d_len > 0 %} <p><b>最常见的词</b></p> @@ -53,5 +53,22 @@ <script src="{{ js }}" ></script> {% endfor %} {% endif %} +<script type="text/javascript"> + // IIFE, avoid polluting the global scope + (function() { + const articleInput = document.querySelector('#article'); + articleInput.value = localStorage.getItem('article') || ''; + + articleInput.addEventListener('input', function() { + localStorage.setItem('article', articleInput.value); + }); + + window.clearArticle = function() { + localStorage.removeItem('article'); + articleInput.value = ''; + }; + })(); + +</script> </body> </html> diff --git a/app/templates/mainpage_post.html b/app/templates/mainpage_post.html index 7357457..5df7dd5 100644 --- a/app/templates/mainpage_post.html +++ b/app/templates/mainpage_post.html @@ -2,7 +2,7 @@ <html lang="en"> <head> <meta charset="UTF-8"> - <title>Title</title> + <title>单词词频</title> {{ yml['header'] | safe }} {% if yml['css']['item'] %} diff --git a/app/templates/reset.html b/app/templates/reset.html index 3425c97..408e001 100644 --- a/app/templates/reset.html +++ b/app/templates/reset.html @@ -12,6 +12,10 @@ alert('输入不能为空!'); return false; } + if (old_password.includes(' ') || new_password.includes(' ')) { + alert('输入不能包含空格!'); + return false; + } if (new_password !== re_new_password) { alert('新密码不匹配,请重新输入'); return false; diff --git a/app/templates/signup.html b/app/templates/signup.html index 5b3aafe..6b5db6e 100644 --- a/app/templates/signup.html +++ b/app/templates/signup.html @@ -16,6 +16,10 @@ You're logged in already! <a href="/logout">Logout</a>. alert('输入不能为空!'); return false; } + if (password.includes(' ') || password2.includes(' ')) { + alert('输入不能包含空格!'); + return false; + } if (password !== password2) { alert('确认密码与输入密码不一致!'); return false; diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html index 4e25725..243166f 100644 --- a/app/templates/userpage_get.html +++ b/app/templates/userpage_get.html @@ -86,7 +86,7 @@ <div> <p><small class="text-muted" id="source">{{ today_article['source'] }}</small></p><br/> </div> - + <p><b id="question">{{ today_article['question'] }}</b></p><br/> <script type="text/javascript"> function toggle_visibility(id) { {# https://css-tricks.com/snippets/javascript/showhide-element/#} @@ -109,22 +109,22 @@ </div> </div> - <input type="checkbox" onclick="toggleHighlighting()" checked/>生词高亮 - <input type="checkbox" onclick="onReadClick()" checked/>大声朗读 - <input type="checkbox" onclick="onChooseClick()" checked/>划词入库 + <input type="checkbox" id="highlightCheckbox" onclick="toggleHighlighting()" />生词高亮 + <input type="checkbox" id="readCheckbox" onclick="onReadClick()" />大声朗读 + <input type="checkbox" id="chooseCheckbox" onclick="onChooseClick()" />划词入库 <div class="range"> <div class="field"> <div class="sliderValue"> <span id="rangeValue">1×</span> </div> - <input type="range" id="rangeComponent" min="0.5" max="2" value="1" step="0.25"/> + <input type="range" id="rangeComponent" min="0.5" max="2" value="1" step="0.25" /> </div> </div> <p><b>收集生词吧</b> (可以在正文中划词,也可以复制黏贴)</p> <form method="post" action="/{{ username }}/userpage"> <textarea name="content" id="selected-words" rows="10" cols="120"></textarea><br/> <button class="btn btn-primary btn-lg" type="submit" onclick="Reader.stopRead()">把生词加入我的生词库</button> - <button class="btn btn-primary btn-lg" type="reset">清除</button> + <button class="btn btn-primary btn-lg" type="reset" onclick="clearSelectedWords()">清除</button> </form> {% if session.get['thisWord'] %} <script type="text/javascript"> @@ -139,7 +139,7 @@ {% if d_len > 0 %} <p> - <b>我的生词簿</b> + <b>我的生词簿</b> <label for="move_dynamiclly"> <input type="checkbox" name="move_dynamiclly" id="move_dynamiclly" checked> 允许动态调整顺序 @@ -175,18 +175,60 @@ <script type="text/javascript"> window.onload = function () { // 页面加载时执行 + const settings = { + // initialize settings from localStorage + highlightChecked: localStorage.getItem('highlightChecked') !== 'false', // localStorage stores strings, default to true. same below + readChecked: localStorage.getItem('readChecked') !== 'false', + chooseChecked: localStorage.getItem('chooseChecked') !== 'false', + rangeValue: localStorage.getItem('rangeValue') || '1', + selectedWords: localStorage.getItem('selectedWords') || '' + }; + + const elements = { + highlightCheckbox: document.querySelector('#highlightCheckbox'), + readCheckbox: document.querySelector('#readCheckbox'), + chooseCheckbox: document.querySelector('#chooseCheckbox'), + rangeComponent: document.querySelector('#rangeComponent'), + rangeValueDisplay: document.querySelector('#rangeValue'), + selectedWordsInput: document.querySelector('#selected-words') + }; + // 应用设置到页面元素 + elements.highlightCheckbox.checked = settings.highlightChecked; + elements.readCheckbox.checked = settings.readChecked; + elements.chooseCheckbox.checked = settings.chooseChecked; + elements.rangeComponent.value = settings.rangeValue; + elements.rangeValueDisplay.textContent = `${settings.rangeValue}x`; + elements.selectedWordsInput.value = settings.selectedWords; + // 刷新页面或进入页面时判断,若不是首篇文章,则上一篇按钮可见 - if(sessionStorage.getItem('pre_page_button')!="display" && sessionStorage.getItem('pre_page_button')){ + if (sessionStorage.getItem('pre_page_button') !== 'display' && sessionStorage.getItem('pre_page_button')) { $('#load_pre_article').show(); } - startTime=Date.now();//记录用户页面的初始时间 - if(window.performance.navigation.type!=1){//将第一次加载页面时的文章id,level保存到本地 - sessionStorage.setItem('article_id','{{today_article['article_id']}}'); - sessionStorage.setItem('text_level','{{today_article['text_level']}}'); + // 事件监听器 + elements.selectedWordsInput.addEventListener('input', () => { + localStorage.setItem('selectedWords', elements.selectedWordsInput.value); + }); + + elements.rangeComponent.addEventListener('input', () => { + const rangeValue = elements.rangeComponent.value; + elements.rangeValueDisplay.textContent = `${rangeValue}x`; + localStorage.setItem('rangeValue', rangeValue); + }); + + startTime=Date.now();//记录用户页面的初始时间 + if(window.performance.navigation.type!=1){//将第一次加载页面时的文章id,level保存到本地 + sessionStorage.setItem('article_id','{{today_article['article_id']}}'); + sessionStorage.setItem('text_level','{{today_article['text_level']}}'); } - // - }; + }; + + function clearSelectedWords() { + localStorage.removeItem('selectedWords'); + document.querySelector('#selected-words').value = ''; + } + + function load_next_article(){ //在进入下一篇之前处理 endTime=Date.now();//记录用户点击下一篇文章时的时间 diff --git a/app/templates/userpage_post.html b/app/templates/userpage_post.html index a7ad569..94816c5 100644 --- a/app/templates/userpage_post.html +++ b/app/templates/userpage_post.html @@ -1,50 +1,50 @@ <!DOCTYPE html> <html lang="en"> <head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=3.0, user-scalable=yes" /> - <meta name="format-detection" content="telephone=no" /> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=3.0, user-scalable=yes" /> + <meta name="format-detection" content="telephone=no" /> - {{ yml['header'] | safe }} - {% if yml['css']['item'] %} - {% for css in yml['css']['item'] %} - <link href="{{ css }}" rel="stylesheet"> - {% endfor %} - {% endif %} - {% if yml['js']['head'] %} - {% for js in yml['js']['head'] %} - <script src="{{ js }}" ></script> - {% endfor %} - {% endif %} + {{ yml['header'] | safe }} + {% if yml['css']['item'] %} + {% for css in yml['css']['item'] %} + <link href="{{ css }}" rel="stylesheet"> + {% endfor %} + {% endif %} + {% if yml['js']['head'] %} + {% for js in yml['js']['head'] %} + <script src="{{ js }}" ></script> + {% endfor %} + {% endif %} - <title>EnglishPal Study Room for {{username}}</title> + <title>EnglishPal Study Room for {{username}}</title> </head> <body> - <div class="container-fluid"> - <p class="mt-md-3"> - <input type="button" id="btn-cancel-selection" value="取消勾选" onclick="toggleCheckboxSelection(false)" /> - <input type="button" id="btn-selection" value="全部勾选" onclick="toggleCheckboxSelection(true)" /> - </p> - <form method="post" action="/{{username}}/mark"> - <button type="submit" name="add-btn" class="btn btn-outline-primary btn-lg">加入我的生词簿</button> - {% for x in lst %} - {% set word = x[0]%} - <p> - <font color="grey">{{loop.index}}</font> - : - <a href='http://youdao.com/w/eng/{{word}}/#keyfrom=dict2.index' title={{word}}>{{word}}</a> - ({{x[1]}}) - <input type="checkbox" name="marked" value="{{word}}" checked> - </p> + <div class="container-fluid"> + <p class="mt-md-3"> + <input type="button" id="btn-cancel-selection" value="取消勾选" onclick="toggleCheckboxSelection(false)" /> + <input type="button" id="btn-selection" value="全部勾选" onclick="toggleCheckboxSelection(true)" /> + </p> + <form method="post" action="/{{username}}/mark"> + <button type="submit" name="add-btn" class="btn btn-outline-primary btn-lg" onclick="clearSelectedWords()">加入我的生词簿</button> + {% for x in lst %} + {% set word = x[0]%} + <p> + <font color="grey">{{loop.index}}</font> + : + <a href='http://youdao.com/w/eng/{{word}}/#keyfrom=dict2.index' title={{word}}>{{word}}</a> + ({{x[1]}}) + <input type="checkbox" name="marked" value="{{word}}" checked> + </p> - {% endfor %} - </form> - {{ yml['footer'] | safe }} - {% if yml['js']['bottom'] %} + {% endfor %} + </form> + {{ yml['footer'] | safe }} + {% if yml['js']['bottom'] %} {% for js in yml['js']['bottom'] %} - <script src="{{ js }}" ></script> + <script src="{{ js }}" ></script> {% endfor %} - {% endif %} - </div> + {% endif %} + </div> </body> </html> diff --git a/app/test/test_bug528_tangjiao.py b/app/test/test_bug528_tangjiao.py new file mode 100644 index 0000000..802423c --- /dev/null +++ b/app/test/test_bug528_tangjiao.py @@ -0,0 +1,95 @@ +import pytest +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from selenium.common.exceptions import NoSuchElementException, TimeoutException + + +# 测试登录页面输入密码包含空格的情况 +def test_login_password_with_space(driver, URL): + try: + driver.get(URL+"/login") + + # 输入用户名 + username_elem = driver.find_element_by_id('username') + username_elem.send_keys("test_user") + + # 输入包含空格的密码 + password_elem = driver.find_element_by_id('password') + password_elem.send_keys("password with space") + + # 提交登录表单 + elem = driver.find_element_by_class_name('btn') # 找到提交按钮 + elem.click() + + # 显式等待直到警告框出现 + WebDriverWait(driver, 10).until(EC.alert_is_present()) + + # 检查是否弹出警告框 + alert = driver.switch_to.alert + assert "输入不能包含空格!" in alert.text + except (NoSuchElementException, TimeoutException) as e: + pytest.fail("页面元素未找到或超时: {}".format(e)) + + +# 测试注册页面输入密码包含空格的情况 + +def test_signup_password_with_space(driver, URL): + try: + driver.get(URL+"/signup") + + # 输入用户名 + username_elem = driver.find_element_by_id('username') + username_elem.send_keys("new_user") + + # 输入包含空格的密码 + password_elem = driver.find_element_by_id('password') + password_elem.send_keys("password with space") + + # 再次输入密码 + password2_elem = driver.find_element_by_id('password2') + password2_elem.send_keys("password with space") + + # 提交注册表单 + elem = driver.find_element_by_class_name('btn') # 找到提交按钮 + elem.click() + + # 显式等待直到警告框出现 + WebDriverWait(driver, 10).until(EC.alert_is_present()) + + # 检查是否弹出警告框 + alert = driver.switch_to.alert + assert "输入不能包含空格!" in alert.text + except (NoSuchElementException, TimeoutException) as e: + pytest.fail("页面元素未找到或超时: {}".format(e)) + + + +# 测试重设密码页面输入新密码包含空格的情况 + +def test_reset_password_with_space(driver, URL): + try: + driver.get(URL+"/reset") + + # 输入用户名 + username_elem = driver.find_element_by_id('username') + username_elem.send_keys("test_user") + + # 输入包含空格的密码 + password_elem = driver.find_element_by_id('password') + password_elem.send_keys("password with space") + + # 提交重设密码表单 + elem = driver.find_element_by_class_name('btn') # 找到提交按钮 + elem.click() + + # 显式等待直到警告框出现 + WebDriverWait(driver, 10).until(EC.alert_is_present()) + + # 检查是否弹出警告框 + alert = driver.switch_to.alert + assert "输入不能包含空格!" in alert.text + except (NoSuchElementException, TimeoutException) as e: + pytest.fail("页面元素未找到或超时: {}".format(e)) diff --git a/app/test/test_bug544_tangxinyuan.py b/app/test/test_bug544_tangxinyuan.py new file mode 100644 index 0000000..43bfa8c --- /dev/null +++ b/app/test/test_bug544_tangxinyuan.py @@ -0,0 +1,53 @@ +import random +import string +from selenium.webdriver.common.by import By +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC + +from helper import signup + + +def has_punctuation(s): + return any(c in string.punctuation for c in s) + + +def login(driver, home, uname, password): + driver.get(home) + WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.LINK_TEXT, '登录'))).click() + driver.find_element(By.ID, 'username').send_keys(uname) + driver.find_element(By.ID, 'password').send_keys(password) + driver.find_element(By.XPATH, '//button[text()="登录"]').click() + WebDriverWait(driver, 10).until(EC.title_is(f"EnglishPal Study Room for {uname}")) + + +def select_valid_word(driver): + elem = driver.find_element(By.ID, 'text-content') + essay_content = elem.text + valid_word = random.choice([word for word in essay_content.split() if len(word) >= 6 and not has_punctuation( + word) and 'font>' not in word and 'br>' not in word and 'p>' not in word]) + driver.find_element(By.ID, 'selected-words').send_keys(valid_word) + return valid_word + + +def test_save_selected_word(driver, URL): + try: + username, password = signup(URL, driver) + word = select_valid_word(driver) + stored_words = driver.execute_script('return localStorage.getItem("selectedWords");') + assert word == stored_words, "Selected word not saved to localStorage correctly" + # 退出并重新登录以检查存储的单词 + driver.find_element(By.LINK_TEXT, '退出').click() + driver.execute_script("window.open('');window.close();") + + # 等待一会儿,让浏览器有足够的时间关闭标签页 + WebDriverWait(driver, 2) + + # 重新打开一个新的标签页 + driver.execute_script("window.open('');") + driver.switch_to.window(driver.window_handles[-1]) # 切换到新打开的标签页 + + login(driver, URL, username, password) + textarea_content = driver.find_element(By.ID, 'selected-words').get_attribute('value') + assert word == textarea_content, "Selected word not preserved after re-login" + finally: + driver.quit() diff --git a/app/test/test_bug551_DingZeYu.py b/app/test/test_bug551_DingZeYu.py new file mode 100644 index 0000000..015fb5a --- /dev/null +++ b/app/test/test_bug551_DingZeYu.py @@ -0,0 +1,37 @@ +import time +import pytest +from selenium import webdriver +from selenium.webdriver import ActionChains +from selenium.webdriver.common.by import By +from selenium.webdriver.common.alert import Alert +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.support.wait import WebDriverWait +from helper import signup + +def test_bug551(driver, URL): + driver.maximize_window() + driver.get(URL) + + username, password = signup(URL, driver) + + article = driver.find_element(By.ID, 'article') + actions = ActionChains(driver) + + actions.move_to_element(article) + actions.click_and_hold() + actions.move_by_offset(450, 200) + actions.release() + actions.perform() + + # 获取选中高亮部分的单词的元素 + highlighted_words = driver.find_elements(By.CLASS_NAME, 'highlighted') + + # 验证选中部分的单词是否同时应用了需求样式 + expected_font_weight = "400" + + for word in highlighted_words: + font_weight = word.value_of_css_property("font-weight") + assert font_weight == expected_font_weight, f"选中部分的单词的字体样式错误" + + time.sleep(5) + driver.quit() diff --git a/app/test/test_bug553_LinShan.py b/app/test/test_bug553_LinShan.py new file mode 100644 index 0000000..388f5da --- /dev/null +++ b/app/test/test_bug553_LinShan.py @@ -0,0 +1,58 @@ +from selenium import webdriver +from selenium.webdriver.common.desired_capabilities import DesiredCapabilities +from selenium.webdriver.support import expected_conditions as EC +from selenium import webdriver +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.common.by import By +from selenium.webdriver.common.keys import Keys +import logging +import time +import pytest + +@pytest.mark.parametrize("test_input,expected", + [("‘test1’", "test1"), + ("'test2'", "test2"), + ("“test3”", "test3"), + ("it's", "it's"), + ("hello,I'm linshan", ["hello","i'm","linshan"]), + ("Happy New Year!?", ["happy","new","year"]), + ("My favorite book is 《Harry Potter》。", ["potter","harry","my","favorite","book","is"])]) +def test_bug553_LinShan(test_input,expected, driver, URL): + try: + # 打开对应地址的网页 + driver.get(URL) + + # 浏览器最大窗口化 + driver.maximize_window() + + # 判断网页源代码中是否有English Pal -文字 + assert 'English Pal -' in driver.page_source + + # 将测试的数据输入到主页的textarea里 + driver.find_element_by_xpath("//textarea[@name='content']").send_keys(Keys.CONTROL, "a") + driver.find_element_by_xpath("//textarea[@name='content']").send_keys(test_input) + time.sleep(1) + + # 点击按钮获取单词 + driver.find_element_by_xpath("//input[@value='get文章中的词频']").click() + time.sleep(1) + + # 获取筛选后的单词 + words = driver.find_elements_by_xpath("//p/a") + + # 遍历获取到的单词,并判断单词与预期的相同 + for word in words: + # 判断单词是否在预期结果中 + assert word.text in expected + + # 返回上一页网页 + driver.find_element_by_xpath("//input[@value='确定并返回']").click() + time.sleep(0.1) + + except Exception as e: + # 输出异常信息 + logging.error(e) + # 关闭浏览器 + driver.quit() + finally: + driver.quit() diff --git a/app/wordfreqCMD.py b/app/wordfreqCMD.py index dcee74e..feeafbd 100644 --- a/app/wordfreqCMD.py +++ b/app/wordfreqCMD.py @@ -4,6 +4,7 @@ ########################################################################### import collections +import html import string import operator import os, sys # 引入模块sys,因为我要用里面的sys.argv列表中的信息来读取命令行参数。 @@ -39,7 +40,8 @@ def file2str(fname):#文件转字符 def remove_punctuation(s): # 这里是s是形参 (parameter)。函数被调用时才给s赋值。 - special_characters = '\_©~<=>+/[]*&$%^@.,?!:;#()"“”—‘’{}|' # 把里面的字符都去掉 + special_characters = '\_©~<=>+/[]*&$%^@.,?!:;#()"“”—‘’{}|,。?!¥……()、《》:;·' # 把里面的字符都去掉 + s = html.unescape(s) # 将HTML实体转换为对应的字符,比如<会被识别为小于号 for c in special_characters: s = s.replace(c, ' ') # 防止出现把 apple,apple 移掉逗号后变成 appleapple 情况 s = s.replace('--', ' ') @@ -104,7 +106,7 @@ if __name__ == '__main__': print('%s\t%d\t%s' % (x[0], x[1], youdao_link(x[0])))#函数导出 # 把频率的结果放result.html中 - make_html_page(sort_in_descending_order(L), 'result.html') + make_html_page(sort_in_descending_order(L), 'result.html') print('\nHistory:\n') if os.path.exists('frequency.p'): diff --git a/requirements.txt b/requirements.txt index 4322f80..4b81c20 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,5 @@ PyYAML~=6.0 pony==0.7.16 snowballstemmer==2.2.0 Werkzeug==2.2.2 + +pytest~=8.1.1 \ No newline at end of file