diff --git a/TMWebDriver.py b/TMWebDriver.py index 86a2b0b..9669777 100644 --- a/TMWebDriver.py +++ b/TMWebDriver.py @@ -34,7 +34,7 @@ class Session: class TMWebDriver: - def __init__(self, host: str = 'localhost', port: int = 18765): + def __init__(self, host: str = '127.0.0.1', port: int = 18765): self.host, self.port = host, port self.sessions, self.results, self.acks = {}, {}, {} self.default_session_id = None @@ -202,7 +202,7 @@ class TMWebDriver: hasjump = acked = False while exec_id not in self.results: - time.sleep(0.5) + time.sleep(0.2) if not acked and exec_id in self.acks: acked = True; start_time = time.time() if tp == 'ws': @@ -266,4 +266,4 @@ class TMWebDriver: return self.execute_js(f'GM_openInTab("{url}");') if __name__ == "__main__": - driver = TMWebDriver(host='localhost', port=18765) \ No newline at end of file + driver = TMWebDriver(host='127.0.0.1', port=18765) \ No newline at end of file diff --git a/assets/ljq_web_driver.user.js b/assets/ljq_web_driver.user.js index 2e90d36..1674be2 100644 --- a/assets/ljq_web_driver.user.js +++ b/assets/ljq_web_driver.user.js @@ -11,7 +11,7 @@ // @grant GM_xmlhttpRequest // @grant GM_openInTab // @grant unsafeWindow -// @connect localhost +// @connect 127.0.0.1 // @run-at document-start // ==/UserScript== @@ -26,13 +26,13 @@ return; } - const wsUrl = 'ws://localhost:18765'; - const httpUrl = 'http://localhost:18766/'; + const wsUrl = 'ws://127.0.0.1:18765'; + const httpUrl = 'http://127.0.0.1:18766/'; function isWebSocketServerAlive(callback) { GM_xmlhttpRequest({ method: 'GET', - url: 'http://localhost:18765/', + url: 'http://127.0.0.1:18765/', onload: () => callback(true), onerror: () => callback(false) }); diff --git a/memory/tmwebdriver_sop.md b/memory/tmwebdriver_sop.md index ad26ebd..a004fc2 100644 --- a/memory/tmwebdriver_sop.md +++ b/memory/tmwebdriver_sop.md @@ -104,4 +104,7 @@ web_scan失败时按序排查: ①TM没装?→遍历本机所有Chromium浏览器(Chrome/Edge/Brave…)用户数据目录下Extensions/,各子目录manifest.json搜"tampermonkey" 没找到→走web_setup_sop;找到→记住装在哪个浏览器 ②浏览器没开?→检查①对应的浏览器进程是否在跑(tasklist/ps),没有则启动并打开正常URL(⚠about:blank等内部页不加载扩展) -③WS后台挂了?→socket.connect_ex(('localhost',18766))非0即dead→手动`from TMWebDriver import TMWebDriver; TMWebDriver()`起master \ No newline at end of file +③WS后台挂了?→socket.connect_ex(('127.0.0.1',18766))非0即dead→手动`from TMWebDriver import TMWebDriver; TMWebDriver()`起master + +## 性能 +- ⚠ URL必须用`127.0.0.1`不用`localhost`。Windows下localhost先尝试IPv6(::1)超时2s再回退IPv4,每次HTTP请求多2s \ No newline at end of file diff --git a/simphtml.py b/simphtml.py index c439dd4..b5294da 100644 --- a/simphtml.py +++ b/simphtml.py @@ -17,12 +17,14 @@ function createEnhancedDOMCopy() { if (sourceNode.nodeType === 3) return sourceNode.cloneNode(false); const clone = sourceNode.cloneNode(false); if ((sourceNode.tagName === 'INPUT' || sourceNode.tagName === 'TEXTAREA') && sourceNode.value) clone.setAttribute('value', sourceNode.value); + if (sourceNode.tagName === 'INPUT' && (sourceNode.type === 'radio' || sourceNode.type === 'checkbox') && sourceNode.checked) clone.setAttribute('checked', ''); else if (sourceNode.tagName === 'SELECT' && sourceNode.value) clone.setAttribute('data-selected', sourceNode.value); try { if (sourceNode.matches && sourceNode.matches(':-webkit-autofill')) { clone.setAttribute('data-autofilled', 'true'); if (!sourceNode.value) clone.setAttribute('value', '⚠️受保护-读tmwebdriver_sop的autofill章节提取'); } } catch(e) {} const isDropdown = sourceNode.classList?.contains('dropdown-menu') || /dropdown|menu/i.test(sourceNode.className) || sourceNode.getAttribute('role') === 'menu'; - const isSmallDropdown = isDropdown && (sourceNode.querySelectorAll('a, button, [role="menuitem"], li').length <= 7 && sourceNode.textContent.length < 500); + const _ddItems = isDropdown ? sourceNode.querySelectorAll('a, button, [role="menuitem"], li').length : 0; + const isSmallDropdown = _ddItems > 0 && _ddItems <= 7 && sourceNode.textContent.length < 500; const childNodes = []; for (const child of sourceNode.childNodes) { @@ -704,6 +706,7 @@ js_findMainContent = ''' def optimize_html_for_tokens(html): if type(html) is str: soup = BeautifulSoup(html, 'html.parser') else: soup = html + for svg in soup.find_all('svg'): svg.clear() [tag.attrs.pop('style', None) for tag in soup.find_all(True)] for tag in soup.find_all(True): if tag.has_attr('src'): @@ -788,6 +791,10 @@ def find_changed_elements(before_html, after_html): for sig, els in after_sigs.items(): if sig not in before_sigs: changed.extend(els) elif len(els) > len(before_sigs[sig]): changed.extend(els[:len(els) - len(before_sigs[sig])]) + if len(changed) == 0 and str(before_soup) != str(after_soup): + before_els, after_els = before_soup.find_all(True), after_soup.find_all(True) + for i in range(min(len(before_els), len(after_els))): + if get_sig(before_els[i]) != get_sig(after_els[i]): changed.append(after_els[i]) # 变化边界: parent不在changed中的元素 cids = set(id(el) for el in changed) boundaries = [el for el in changed if el.parent is None or id(el.parent) not in cids]