浏览器调用GoldenDict查词
2021/11/6 6:40:53
本文主要是介绍浏览器调用GoldenDict查词,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
浏览器调用GoldenDict查词
GoldenDict不支持对Windows平台中Firefox浏览器的网页查词,下面提供一种利用Tampermonkey和Python配合实现查词的方案。
方案探索
在网络上可以查到执行GoldenDict.exe hello
这条命令可以调出GoldenDict对hello
这个词的查询小窗口,遂想到去看一下源代码中是怎么实现的。
在源代码的main.cc
中的main
函数有如下一行代码:
app.sendMessage( QString( "translateWord: " ) + gdcl.wordToTranslate() );
从这里我想到模拟这行代码是不是就可以调出查词小窗口。在网上搜寻一番后在https://github.com/qtproject/qt-solutions/blob/master/qtsingleapplication/src/qtlocalpeer.cpp
找到了 sendMessage
的实现。
下面就是使用Python编写模仿调用的代码了,在代码中需注意函数connectToServer
的参数需要通过C:\Users\username\AppData\Local\Temp\qtsingleapp-Golden-86bf-3-lockfile
或使用Procexe.exe
查看GoldenDict.exe的句柄列表,如:\Device\NamedPipe\qtsingleapp-Golden-86bf-3
。这个参数是在QtLocalPeer
的构造函数中生成的,不同的电脑值可能不一样。
步骤
本方案仅供演示。
一、编写Tampermonkey用户脚本实现一个在网页中划词翻译的界面,选中词语后请求由Python脚本Web服务器提供的特定网址。
let id = 0 window.addEventListener('mouseup',(e)=>{ let s = window.getSelection(); if(s.toString().length > 0) { let elm = document.getElementById('goldendict') if (e.target === elm){ return } elm.style.left = `${e.clientX}px` elm.style.top = `${e.clientY}px` elm.style.marginTop = window.getComputedStyle(s.anchorNode.parentElement)['font-size'] elm.style.visibility = 'visible' elm.classList.toggle('dictshow',true) let lid = setTimeout(function(){ if(id != lid) return elm.style.visibility = 'hidden' },3000) id = lid } }) function initdict() { document.body.insertAdjacentHTML('beforeend', `<style>#goldendict.dictshow:hover{visibility:visible !important;}</style> <button id="goldendict" class="dictshow" style="position:fixed;top:-100px;left:0px;width: max-content;background:white;" onclick="fetch('http://localhost:8080/query/'+window.getSelection().toString());this.classList.toggle('dictshow',false);this.style.visibility='hidden';" >Search</button>`) } initdict()
效果如下:
二、编写Python脚本,接受浏览器请求,调用GoldenDict查词
要向GoldenDict传递信息需要安装PyQt5。最简单做法就是分析出要查的词后,直接调用os.system('GoldenDict.exe '+ word)
,这里使用Qt的LocalSocket。
代码由两部分组成:
- 简单的Web服务器
- 对照参考链接2中的
QtLocalPeer::sendMessage
函数编写的__opendict
import os import re from flask import Flask from PyQt5.QtCore import QDataStream,QByteArray from PyQt5.QtNetwork import QLocalSocket import http.server import socketserver import json timeout = 3000 port = 8080 class HTTPRequestHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): print(self.path) words = re.findall('^/query/([^/]+)$', self.path) if len(words) == 0: self.__send_code(404) return self.__send_code(200) self.__opendict(words[0]) def __send_code(self, code): self.send_response(code) self.send_header('Access-Control-Allow-Origin', '*') self.end_headers() def __opendict(self, word): try: # 没搞清楚怎么重复使用QLocalSocket soc = QLocalSocket() # 换成你电脑上的值 soc.connectToServer('qtsingleapp-Golden-86bf-3') if not soc.waitForConnected(timeout): print(soc.errorString()) return qdata = QDataStream(soc) if len(word) == 0: return msg = 'translateWord: ' + word qb = QByteArray(msg.encode()) qdata.writeBytes(qb) s = soc.waitForBytesWritten(timeout) if s: s &= soc.waitForReadyRead(timeout) if s: print(soc.readAll().data().decode()) soc.disconnectFromServer() print('LocalSocketError:%d'%(soc.error())) print('LocalSocketState:%d'%(soc.state())) except Exception as e: raise e finally: soc.disconnectFromServer() soc.close() print("Socked Closed.") httpd = socketserver.TCPServer(('', port), HTTPRequestHandler) try: httpd.serve_forever() except KeyboardInterrupt: httpd.shutdown() exit()
在浏览器中访问http://localhost:8080/query/word
,GoldenDict会在你鼠标指针处弹出查词小窗口。
参考链接:
https://github.com/goldendict/goldendict/blob/master/main.cc
https://github.com/qtproject/qt-solutions/blob/master/qtsingleapplication/src/qtlocalpeer.cpp
https://doc.qt.io/qt-5/qlocalsocket.html
https://stackoverflow.com/questions/12712360/qtsingleapplication-for-pyside-or-pyqt
这篇关于浏览器调用GoldenDict查词的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23MongoDB身份认证机制揭秘!
- 2024-11-20MongoDB教程:从入门到实践详解
- 2024-11-17执行 Google Ads API 查询后返回的是空数组什么原因?-icode9专业技术文章分享
- 2024-11-17google广告数据不同经理账户下的凭证可以获取对方的api数据吗?-icode9专业技术文章分享
- 2024-11-15SendGrid 的 Go 客户端库怎么实现同时向多个邮箱发送邮件?-icode9专业技术文章分享
- 2024-11-15SendGrid 的 Go 客户端库怎么设置header 和 标签tag 呢?-icode9专业技术文章分享
- 2024-11-12Cargo deny安装指路
- 2024-11-02MongoDB项目实战:从入门到初级应用
- 2024-11-01随时随地一键转录,Google Cloud 新模型 Chirp 2 让语音识别更上一层楼
- 2024-10-25Google Cloud动手实验详解:如何在Cloud Run上开发无服务器应用