本文介紹我使用QQ得到服務(wù)器上回傳的python代碼的探索歷程,面向的對(duì)象是對(duì)計(jì)算機(jī)網(wǎng)絡(luò)有一定了解的讀者。期待有興趣的人和我一起探討!
需求來(lái)源
最近,我在跑一些數(shù)據(jù)量巨大的代碼。代碼在本地一運(yùn)行,CPU就占滿了,代碼運(yùn)行時(shí)間又久,因此這段時(shí)間根本用不了電腦,這對(duì)疫情在家的大學(xué)生很難受。把代碼放服務(wù)器吧,又不知道什么時(shí)候能跑完,這讓我很不爽。于是,我希望服務(wù)器端的代碼能給我一個(gè)不錯(cuò)的反饋,由此我選擇了QQ交互方法。
硬件工具
本地電腦一臺(tái),服務(wù)器一臺(tái)(如果你只是想嘗試一下,而沒(méi)有服務(wù)器,可以使用 VMware 虛擬機(jī))
探索歷程
首先,我使用的無(wú)界面CentOS服務(wù)器上是沒(méi)有辦法運(yùn)行QQ的,因此想要實(shí)現(xiàn)交互,應(yīng)該先把服務(wù)器上的信息傳送到本地電腦,再由本地電腦發(fā)送給QQ,這樣我就可以收到消息了。
那么就將目標(biāo)分割為兩個(gè)任務(wù)了,分別為:
- 本地電腦給QQ發(fā)信息
- 服務(wù)器與本地電腦信息交互
接下來(lái)就給大家說(shuō)明我是怎么實(shí)現(xiàn)這兩步的:
本地電腦給QQ發(fā)信息
主要原理:通過(guò) win32 API, 將python信息賦給剪切板,粘貼到QQ聊天框中,最后模擬按 “Enter” 鍵,發(fā)送消息
import win32gui
import win32con
import win32clipboard as w
class SendMsg:
"""
這是一個(gè)用于將信息發(fā)送到QQ的類, 使用方法為 :
SendMsg("收信人QQ昵稱", "信息").sendmsg()
注意一點(diǎn),收信人的QQ聊天窗口要在屏幕上,不能最小化或被掩蓋。
"""
def __init__(self, receiver, msg):
self.receiver = receiver
self.msg = msg
self.set_text()
# 設(shè)置剪貼版內(nèi)容
def set_text(self):
w.OpenClipboard()
w.EmptyClipboard()
w.SetClipboardData(win32con.CF_UNICODETEXT, self.msg)
w.CloseClipboard()
# 發(fā)送消息
def sendmsg(self):
qq = win32gui.FindWindow(None, self.receiver)
win32gui.SendMessage(qq, win32con.WM_PASTE, 0, 0)
win32gui.SendMessage(qq, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
if __name__ == '__main__':
SendMsg("一花一世界", "Hello, world").sendmsg()
效果如圖所示:

注意:
1、python 關(guān)于 win32 的包,下載方式為:
2、QQ有兩種發(fā)送消息的模式,一種是"Enter",一種是"Ctrl+Enter"。這里要選擇"Enter"模式。
服務(wù)器與本地電腦信息交互
我們已經(jīng)完成了本地電腦給QQ發(fā)信息的操作,現(xiàn)在只需要完成服務(wù)器與本地電腦信息的交互,就可以讓本地電腦根據(jù)服務(wù)器的指令發(fā)送QQ信息了。
如何讓服務(wù)器和本地電腦通信呢?經(jīng)過(guò)一些思考,我選擇用Socket2。使用Socket的話,就要解決IP問(wèn)題,因?yàn)楸镜仉娔X的IP不是公網(wǎng)IP,我們需要解決端口映射問(wèn)題,將本地電腦的IP映射到公網(wǎng)!
考慮到不一定有路由器,我使用了一款軟件路由俠,該軟件在免費(fèi)的狀態(tài)下,一個(gè)月可以有一個(gè)G的流量進(jìn)行端口映射,因?yàn)槲覀冎饕糜谛《挝淖謧鬏?,這點(diǎn)流量已經(jīng)足夠。該軟件也操作簡(jiǎn)單,我不過(guò)多介紹。
本地電腦開(kāi)放的端口為8080端口,經(jīng)過(guò)路由俠的端口映射后,端口變?yōu)閥ihuahuahua.e2.luyouxia.net:30985
因?yàn)槲覀冎挥米鰡蜗蛲ㄐ?,所以服?wù)器的IP不重要。
我們首先測(cè)試一下Socket功能,讓服務(wù)器給本地電腦發(fā)一個(gè)"Hello world"
代碼如下:
本地電腦端代碼
from socket import *
HOST = ''
PORT = 8080
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
while True:
print('waiting for connection...')
tcpCliSock, addr = tcpSerSock.accept()
print('...connnecting from:', addr)
while True:
data = tcpCliSock.recv(BUFSIZ)
if not data:
break
print(data.decode('utf-8'))
tcpCliSock.close()
tcpSerSock.close()
服務(wù)器端代碼
from socket import *
HOST = 'yihuahuahua.e2.luyouxia.net'
PORT = 30985
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)
output_str = "Hello world!"
tcpCliSock.send(output_str.encode())
tcpCliSock.close()
注意:在進(jìn)行Socket通信時(shí),要注意開(kāi)放端口?。?!
將功能綜合
這里規(guī)定一個(gè)任務(wù):計(jì)算1加1的值,并返回計(jì)算時(shí)間,將上述功能綜合后,代碼如下:
本地電腦端代碼
from socket import *
import win32gui
import win32con
import win32clipboard as w
class SendMsg:
"""
這是一個(gè)用于將信息發(fā)送到QQ的類, 使用方法為 :
SendMsg("收信人QQ昵稱", "信息").sendmsg()
注意一點(diǎn),收信人的QQ聊天窗口要在屏幕上,不能最小化或被掩蓋。
"""
def __init__(self, receiver, msg):
self.receiver = receiver
self.msg = msg
self.set_text()
# 設(shè)置剪貼版內(nèi)容
def set_text(self):
w.OpenClipboard()
w.EmptyClipboard()
w.SetClipboardData(win32con.CF_UNICODETEXT, self.msg)
w.CloseClipboard()
# 發(fā)送消息
def sendmsg(self):
qq = win32gui.FindWindow(None, self.receiver)
win32gui.SendMessage(qq, win32con.WM_PASTE, 0, 0)
win32gui.SendMessage(qq, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
if __name__ == '__main__':
HOST = ''
PORT = 8080
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
while True:
tcpCliSock, addr = tcpSerSock.accept()
while True:
data = tcpCliSock.recv(BUFSIZ)
if not data:
break
output_str = data.decode('utf-8')
SendMsg("一花一世界", output_str).sendmsg()
tcpCliSock.close()
tcpSerSock.close()
服務(wù)器端代碼
from socket import *
import time
HOST = 'yihuahuahua.e2.luyouxia.net'
PORT = 30985
BUFSIZ =1024
ADDR = (HOST,PORT)
tcpCliSock = socket(AF_INET,SOCK_STREAM)
tcpCliSock.connect(ADDR)
start = time.time()
count = 1 + 1
end = time.time()
output_str = "結(jié)果為" + str(count) + " 消耗時(shí)間" + str(int(end - start)) + "秒"
tcpCliSock.send(output_str.encode())
tcpCliSock.close()
運(yùn)行結(jié)果:

美滋滋。
改進(jìn)方向與探索
目前已知的缺陷有:Socket第一次通信有概率收不到消息,第二次就好了…希望有大佬在評(píng)論區(qū)指出我的不足。
這個(gè)版本只能實(shí)現(xiàn)單方面信息傳送,如果想實(shí)現(xiàn)雙向的,我思考的一個(gè)思路是通過(guò) 酷QAir的QQ機(jī)器人 加上 CQHTTP3 插件配合nonebot庫(kù)4來(lái)實(shí)現(xiàn)。不過(guò)我的需求已經(jīng)實(shí)現(xiàn)了,暫時(shí)懶得動(dòng)手了,有緣再探索吧。
https://www.cnblogs.com/hwj2019/p/11552055.html ↩︎
https://blog.csdn.net/su_bao/article/details/80380465 ↩︎
https://github.com/richardchien/coolq-http-api ↩︎
https://nonebot.cqp.moe/guide/getting-started.html ↩︎
總結(jié)
到此這篇關(guān)于我將服務(wù)器上的python代碼通過(guò)QQ發(fā)送回傳信息(附實(shí)現(xiàn)方法)的文章就介紹到這了,更多相關(guān)python qq發(fā)送回傳信息內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- Python Tornado實(shí)現(xiàn)WEB服務(wù)器Socket服務(wù)器共存并實(shí)現(xiàn)交互的方法
- 在服務(wù)器上安裝python3.8.2環(huán)境的教程詳解
- 文件上傳服務(wù)器-jupyter 中python解壓及壓縮方式
- python中的socket實(shí)現(xiàn)ftp客戶端和服務(wù)器收發(fā)文件及md5加密文件
- mac 上配置Pycharm連接遠(yuǎn)程服務(wù)器并實(shí)現(xiàn)使用遠(yuǎn)程服務(wù)器Python解釋器的方法
- 使用 Python ssh 遠(yuǎn)程登陸服務(wù)器的最佳方案
- python實(shí)現(xiàn)從ftp服務(wù)器下載文件
- 基于python實(shí)現(xiàn)簡(jiǎn)單網(wǎng)頁(yè)服務(wù)器代碼實(shí)例