python剪切板(一文教會你用Python實現最有效的剪切板實時監控)
2023-04-20 16:15:35 1
前言上網瀏覽網頁的時候,看見好的內容免不了要使用複製粘貼,但是我們看到的內容、心裡想要的內容和實際粘貼後的內容往往不一致。數據的獲取始於複製,終於粘貼,那麼問題來了,在這中間系統做了哪些操作,我們怎麼能控制它呢?
碼農的日常~
人生苦短,我用python,查閱相關資料之後發現有很多不一樣的實現方式,如利用內置ctypes模塊、tk模塊,第三方模塊如跨平臺的pyperclip模塊、clipboard模塊、pywin.win32clipboard模塊等等,大部分都封裝好了簡潔易用的高級接口,方便我們直接使用。
用最簡單的方式獲取你想要的數據
基於強迫症的心理,本文分析比較了幾種主流的方式,對他們逐一進行源碼分析、讀寫性能實測,最後選擇了讀寫速度最快的一種做出一個實時剪切板監控小案例,以供大家參考。
小案例實現的功能如下:
實時監測ctrl c剪切板寫入事件,去除剪切板中指定字符或文本,如CSDN的複製版權後綴 (¬_¬)瞄。使用正則對某些文本進行智能替換,如將python2格式的代碼轉換為python3格式。方式一:調用第三方pyperclip模塊In [1]: import pyperclipIn [2]: data = pyperclip.pasteIn [3]: dataOut[3]: "print 'Hello World'\r\n————————————————\r\n版權聲明:本文為CSDN博主「...」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結及本聲明。\r\n原文連結:https://blog.csdn.net/.../article/details/..."In [4]: data = data[7:12]In [5]: pyperclip.copy(data)In [6]: pyperclip.pasteOut[6]: 'Hello'
源碼實現:調用內置ctypes模塊中的ctypes.windll.user32接口編寫,和pandas包的代碼一致,代碼位置:pandas.io.clipboard.windows,代碼引用如下
import ctypeswindll = ctypes.windllsafeGetClipboardData = CheckedCall(windll.user32.GetClipboardData)safeGetClipboardData.argtypes = [UINT]safeGetClipboardData.restype = HANDLEsafeSetClipboardData = CheckedCall(windll.user32.SetClipboardData)safeSetClipboardData.argtypes = [UINT, HANDLE]safeSetClipboardData.restype = HANDLE
優點:跨平臺,接口調用方便簡潔
缺點:剪切板的數據格式只支持utf-8文本,頻繁讀寫速度較慢
方式二:調用第三方win32clipboard模塊In [1]: import win32clipboard ...: ...: def clipboard_get: ...: """獲取剪貼板數據""" ...: win32clipboard.OpenClipboard ...: data = win32clipboard.GetClipboardData ...: win32clipboard.CloseClipboard ...: return data ...: ...: def clipboard_set(data): ...: """設置剪貼板數據""" ...: win32clipboard.OpenClipboard ...: win32clipboard.SetClipboardData(13, data) ...: win32clipboard.CloseClipboard ...: return True ...:In [2]: data = clipboard_getIn [3]: dataOut[3]: "print 'Hello World'\r\n————————————————\r\n版權聲明:本文為CSDN博主「...」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上 原文出處連結及本聲明。\r\n原文連結:https://blog.csdn.net/.../article/details/..."In [4]: clipboard_set(data[7:12])Out[4]: TrueIn [5]: clipboard_getOut[5]: 'Hello'
源碼實現:C源碼封裝,python接口調用如下
def GetClipboardData(*args, **kwargs): # real signature unknown passdef SetClipboardData(*args, **kwargs): # real signature unknown pass
優點:原生C封裝讀寫速度最快,支持多種剪切板數據格式
缺點:只適用於windows平臺,高頻率讀寫會報錯需要小心處理,utf-8格式之外的數據格式需要熟悉winuser.h庫自行設計編寫
方法三:調用內置tkinter模塊In [1]: from tkinter import * ...: ...: r = TkIn [2]: data = r.clipboard_getIn [3]: dataOut[3]: "print 'Hello World'\n————————————————\n版權聲明:本文為CSDN博主「...」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文 出處連結及本聲明。\n原文連結:https://blog.csdn.net/.../article/details/..."In [4]: r.clipboard_append(data[7:12])In [5]: r.clipboard_getOut[6]: 'Hello'
注意:在win10系統測試後發現,使用tkinter模塊只能獲取剪切板數據,不能將數據寫入剪切板,外部調用clipboard_board方法時,系統剪切板進程會被tk接管鎖死,此時在其他的應用按ctrl v,粘貼的應用會直接處於卡死的狀態,或者粘貼後內容為空。
如果還是通過Tk對象將數據寫入剪切板,只能採取下面的方法,設置延遲銷毀Tk對象,系統剪切板數據才會被更新,否則內容還是為空(實測如果設置0.2秒以內的頻率讀取,剪切板還是為空,這就很雞肋了):
from tkinter import *import timer = Tkr.withdrawr.clipboard_clearr.clipboard_append('some string')r.updatetime.sleep(.2)r.updater.destroy
源碼實現:C源碼封裝,python接口調用如下
# 讀取剪切板數據:_tkinter.tkapp('clipboard', 'get')# 寫入剪切板數據:_tkinter.tkapp('clipboard', 'append')
剪切板讀寫速度測試結果性能對比
實時監控小案例:運行效果:
【Copy text】:print 'Hello World' \r\n————————————————\r\n版權聲明:本文為CSDN博主「...」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上 原文出處連結及本聲明。\r\n原文連結:https://blog.csdn.net/.../article/details/...【After replace:】:print('Hello World')
參考連結:微軟開發文檔:https://docs.microsoft.com/zh-cn/windows/win32/dataxchg/using-the-clipboard?redirectedfrom=MSDN#_win32_Copying_Information_to_the_ClipboardStack Overflow:https://stackoverflow.com/questions/579687/how-do-i-copy-a-string-to-the-clipboard-on-windows-using-python
這是一個數據爆炸的時代
,