perf: localhost→127.0.0.1 fix IPv6 2s delay; simphtml radio/checkbox/svg/dropdown fixes; poll interval 0.5→0.2s
This commit is contained in:
@@ -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)
|
||||
driver = TMWebDriver(host='127.0.0.1', port=18765)
|
||||
@@ -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)
|
||||
});
|
||||
|
||||
@@ -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
|
||||
③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
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user