1. 程式人生 > 程式設計 >如何將伺服器上的python程式碼通過QQ傳送回傳資訊(附實現方法)

如何將伺服器上的python程式碼通過QQ傳送回傳資訊(附實現方法)

本文介紹我使用QQ得到伺服器上回傳的python程式碼的探索歷程,面向的物件是對計算機網路有一定了解的讀者。期待有興趣的人和我一起探討!

需求來源

最近,我在跑一些資料量巨大的程式碼。程式碼在本地一執行,CPU就佔滿了,程式碼執行時間又久,因此這段時間根本用不了電腦,這對疫情在家的大學生很難受。把程式碼放伺服器吧,又不知道什麼時候能跑完,這讓我很不爽。於是,我希望伺服器端的程式碼能給我一個不錯的反饋,由此我選擇了QQ互動方法。

硬體工具

本地電腦一臺,伺服器一臺(如果你只是想嘗試一下,而沒有伺服器,可以使用 VMware 虛擬機器)

探索歷程

首先,我使用的無介面CentOS伺服器上是沒有辦法執行QQ的,因此想要實現互動,應該先把伺服器上的資訊傳送到本地電腦,再由本地電腦傳送給QQ,這樣我就可以收到訊息了。

那麼就將目標分割為兩個任務了,分別為:

  • 本地電腦給QQ發信息
  • 伺服器與本地電腦資訊互動

接下來就給大家說明我是怎麼實現這兩步的:

本地電腦給QQ發信息

主要原理:通過 win32 API,將python資訊賦給剪下板,貼上到QQ聊天框中,最後模擬按 “Enter” 鍵,傳送訊息1。
程式碼如下:

import win32gui
import win32con
import win32clipboard as w


class SendMsg:
 """

 這是一個用於將資訊傳送到QQ的類, 使用方法為 :
 SendMsg("收信人QQ暱稱","資訊").sendmsg()
 注意一點,收信人的QQ聊天視窗要在螢幕上,不能最小化或被掩蓋。

 """

 def __init__(self,receiver,msg):
 self.receiver = receiver
 self.msg = msg
 self.set_text()

 # 設定剪貼版內容
 def set_text(self):
 w.OpenClipboard()
 w.EmptyClipboard()
 w.SetClipboardData(win32con.CF_UNICODETEXT,self.msg)
 w.CloseClipboard()

 # 傳送訊息
 def sendmsg(self):
 qq = win32gui.FindWindow(None,self.receiver)
 win32gui.SendMessage(qq,win32con.WM_PASTE,0)
 win32gui.SendMessage(qq,win32con.WM_KEYDOWN,win32con.VK_RETURN,0)


if __name__ == '__main__':
 SendMsg("一花一世界","Hello,world").sendmsg()

效果如圖所示:

在這裡插入圖片描述

注意:

1、python 關於 win32 的包,下載方式為:

pip install pypiwin32

2、QQ有兩種傳送訊息的模式,一種是"Enter",一種是"Ctrl+Enter"。這裡要選擇"Enter"模式。

伺服器與本地電腦資訊互動

我們已經完成了本地電腦給QQ發信息的操作,現在只需要完成伺服器與本地電腦資訊的互動,就可以讓本地電腦根據伺服器的指令傳送QQ資訊了。
如何讓伺服器和本地電腦通訊呢?經過一些思考,我選擇用Socket2。使用Socket的話,就要解決IP問題,因為本地電腦的IP不是公網IP,我們需要解決埠對映問題,將本地電腦的IP對映到公網!

考慮到不一定有路由器,我使用了一款軟體路由俠,該軟體在免費的狀態下,一個月可以有一個G的流量進行埠對映,因為我們主要用於小段文字傳輸,這點流量已經足夠。該軟體也操作簡單,我不過多介紹。
本地電腦開放的埠為8080埠,經過路由俠的埠對映後,埠變為yihuahuahua.e2.luyouxia.net:30985
因為我們只用做單向通訊,所以伺服器的IP不重要。
我們首先測試一下Socket功能,讓伺服器給本地電腦發一個"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()

伺服器端程式碼

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()

注意:在進行Socket通訊時,要注意開放埠!!!

將功能綜合

這裡規定一個任務:計算1加1的值,並返回計算時間,將上述功能綜合後,程式碼如下:
本地電腦端程式碼

from socket import *
import win32gui
import win32con
import win32clipboard as w


class SendMsg:
 """

 這是一個用於將資訊傳送到QQ的類, 使用方法為 :
 SendMsg("收信人QQ暱稱",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()

伺服器端程式碼

from socket import *
import time
HOST = 'yihuahuahua.e2.luyouxia.net'
PORT = 30985
BUFSIZ =1024
ADDR = (HOST,SOCK_STREAM)
tcpCliSock.connect(ADDR)
start = time.time()
count = 1 + 1
end = time.time()
output_str = "結果為" + str(count) + " 消耗時間" + str(int(end - start)) + "秒"
tcpCliSock.send(output_str.encode())
tcpCliSock.close()

執行結果:

在這裡插入圖片描述

美滋滋。

改進方向與探索

目前已知的缺陷有:Socket第一次通訊有概率收不到訊息,第二次就好了…希望有大佬在評論區指出我的不足。

這個版本只能實現單方面資訊傳送,如果想實現雙向的,我思考的一個思路是通過 酷QAir的QQ機器人 加上 CQHTTP3 外掛配合nonebot庫4來實現。不過我的需求已經實現了,暫時懶得動手了,有緣再探索吧。

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 ↩︎

總結

到此這篇關於我將伺服器上的python程式碼通過QQ傳送回傳資訊(附實現方法)的文章就介紹到這了,更多相關python qq傳送回傳資訊內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!