ฉันจะอ่านข้อความจากคลิปบอร์ด (windows) จาก python ได้อย่างไร


97

ฉันจะอ่านข้อความจากคลิปบอร์ด (windows) จาก python ได้อย่างไร


3
เกี่ยวข้องกับคำถามนี้
glglgl

ในกรณีของฉันเพียงแดนคำตอบที่ทำงานซึ่งใช้คลิปบอร์ดแพคเกจ
Soorena

คำตอบ:


106

คุณสามารถใช้โมดูลที่เรียกว่าwin32clipboardซึ่งเป็นส่วนหนึ่งของpywin32

นี่คือตัวอย่างที่ตั้งค่าข้อมูลคลิปบอร์ดก่อนจากนั้นจึงรับข้อมูล:

import win32clipboard

# set clipboard data
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText('testing 123')
win32clipboard.CloseClipboard()

# get clipboard data
win32clipboard.OpenClipboard()
data = win32clipboard.GetClipboardData()
win32clipboard.CloseClipboard()
print data

คำเตือนที่สำคัญจากเอกสารประกอบ:

เมื่อหน้าต่างตรวจสอบหรือเปลี่ยนคลิปบอร์ดเสร็จแล้วให้ปิดคลิปบอร์ดโดยเรียก CloseClipboard ซึ่งทำให้หน้าต่างอื่น ๆ สามารถเข้าถึงคลิปบอร์ดได้ อย่าวางวัตถุบนคลิปบอร์ดหลังจากเรียก CloseClipboard


6
คุณรู้หรือไม่ว่ามีวิธีใช้คำสั่ง `with´ หรือไม่?
Norfeldt

3
ที่น่าสังเกตใน py34, win7 SetClipboardText ไม่ทำงานหากไม่มีการเรียกก่อนหน้านี้ไปยัง EmptyClipboard
CoderTao

โมดูลนี้มีประโยชน์หากคุณต้องการดำเนินการที่ซับซ้อนมากขึ้นเช่นการนำเนื้อหาที่จัดรูปแบบ HTML ออกจากคลิปบอร์ด ดูstackoverflow.com/questions/17298897/…
xji

2
@Norfeldt หากไม่มีวิธีดั้งเดิมคุณสามารถสร้างวัตถุที่กำหนดเองของคุณเองได้อย่างง่ายดายที่รองรับ "with"
Elijas Dapšauskas

42

คุณสามารถทำได้อย่างง่ายดายผ่านโมดูลในตัวTkinterซึ่งโดยพื้นฐานแล้วเป็นไลบรารี GUI รหัสนี้สร้างวิดเจ็ตเปล่าเพื่อรับเนื้อหาคลิปบอร์ดจาก OS

#from tkinter import Tk  # Python 3
from Tkinter import Tk
Tk().clipboard_get()

2
โปรดเพิ่มความคิดเห็นในรหัสนี้และ (อาจ) ลิงก์ไปยังเอกสารผู้เปิดเผย
jb.

7
ควรจะแทนtkinter Tkinterในทางกลับกันมันใช้ไม่ได้กับ python 3.7.3 64bit win10 ของฉัน
jerik

21

ฉันเห็นคำแนะนำมากมายในการใช้โมดูล win32 แต่ Tkinter มีวิธีที่สั้นและง่ายที่สุดที่ฉันเคยเห็นดังในโพสต์นี้: ฉันจะคัดลอกสตริงไปยังคลิปบอร์ดบน Windows โดยใช้ Python ได้อย่างไร

นอกจากนี้ Tkinter ยังอยู่ในไลบรารีมาตรฐาน python


3
บางโค้ดที่จะได้รับค่าคลิปบอร์ดผ่าน Tkinter: จาก Tkinter import Tk [\ nl] r = Tk () [\ nl] result = r.selection_get (selection = "CLIPBOARD") [\ nl] r.destroy ()
mgkrebbs

18

หากคุณไม่ต้องการติดตั้งแพ็คเกจเสริมctypesก็สามารถทำงานให้ลุล่วงได้เช่นกัน

import ctypes

CF_TEXT = 1

kernel32 = ctypes.windll.kernel32
kernel32.GlobalLock.argtypes = [ctypes.c_void_p]
kernel32.GlobalLock.restype = ctypes.c_void_p
kernel32.GlobalUnlock.argtypes = [ctypes.c_void_p]
user32 = ctypes.windll.user32
user32.GetClipboardData.restype = ctypes.c_void_p

def get_clipboard_text():
    user32.OpenClipboard(0)
    try:
        if user32.IsClipboardFormatAvailable(CF_TEXT):
            data = user32.GetClipboardData(CF_TEXT)
            data_locked = kernel32.GlobalLock(data)
            text = ctypes.c_char_p(data_locked)
            value = text.value
            kernel32.GlobalUnlock(data_locked)
            return value
    finally:
        user32.CloseClipboard()

print(get_clipboard_text())

ดูเหมือนจะใช้ไม่ได้กับ Windows 10 แต่จะพิมพ์คำว่า "None" เสมอ
Aran-Fey

Windows 10 ทำงานได้ดีสำหรับฉันตราบใดที่ฉันใช้ Python 32 บิต ฉันอัปเดตคำตอบเพื่อทำงานกับ 64 บิตเช่นกัน
kichik

ไปที่ข้อผิดพลาดนี้ "ตัวชี้ถ่านที่คาดไว้มี int" ในบรรทัด "text = ctypes.c_char_p (data_locked)" มีความคิดอย่างไร
txemsukr

1
จะเป็นการดีที่จะเห็นวิธีการที่คล้ายกันในการคัดลอกข้อความไปยังคลิปบอร์ดด้วย
mrkbutty

18

ฉันพบว่านี่เป็นวิธีที่ง่ายที่สุดในการเข้าถึงคลิปบอร์ดจาก python:

1) ติดตั้ง pyperclip: pip install pyperclip

2) การใช้งาน:

import pyperclip

s = pyperclip.paste()
pyperclip.copy(s)

# the type of s is string

ทดสอบบน Win10 64-bit, Python 3.5 และ Python 3.7.3 (64-bit) ดูเหมือนว่าจะทำงานกับอักขระที่ไม่ใช่ ASCII ด้วย อักขระที่ทดสอบ ได้แก่ ±°©©αβγθΔΨΦåäö


เหมาะสำหรับ 3.6 หรือไม่ มันถูกติดตั้งสำเร็จ แต่เมื่อใช้วิธีการวาง () มันทำให้ฉันมีข้อผิดพลาด: "จากเวอร์ชันการนำเข้าPySide เป็น PYSIDE_VERSION # การวิเคราะห์: ละเว้น ModuleNotFoundError: ไม่มีโมดูลชื่อ 'PySide'" เมื่อฉันลองติดตั้ง Pyside มันแจ้งว่าไม่รองรับใน 3.6
gaurav

ใช่มันควรจะทำงานบน Python 3.6 และฉันเพิ่งทดสอบกับ Python 3.7.4 (64-bit) ดูที่setup.pyของแพ็คเกจไม่ควรมีการอ้างอิงกับ Pyside หรือแพ็คเกจอื่น ๆ คุณแน่ใจหรือไม่ว่าคำสั่ง paste พยายามใช้ Pyside
np8

ใช่คำสั่งวางกำลังมองหา Pyside และเนื่องจาก Pyside รองรับได้ไม่เกิน python 3.4 เท่านั้นจึงทำให้เกิดข้อผิดพลาด
gaurav

ดูเหมือนว่าจะเป็นวิธีที่ง่ายที่สุดสำหรับ WSL ด้วย
python3.6

11

คำตอบที่ได้รับการโหวตมากที่สุดข้างต้นนั้นแปลกตรงที่เพียงแค่ล้างคลิปบอร์ดแล้วรับเนื้อหา (ซึ่งว่างเปล่า) เราสามารถล้างคลิปบอร์ดเพื่อให้แน่ใจว่าเนื้อหาคลิปบอร์ดบางประเภทเช่น "ข้อความที่จัดรูปแบบ" ไม่ "ครอบคลุม" เนื้อหาข้อความธรรมดาที่คุณต้องการบันทึกในคลิปบอร์ด

โค้ดต่อไปนี้จะแทนที่บรรทัดใหม่ทั้งหมดในคลิปบอร์ดด้วยการเว้นวรรคจากนั้นจะลบช่องว่างคู่ทั้งหมดและบันทึกเนื้อหากลับไปที่คลิปบอร์ด:

import win32clipboard

win32clipboard.OpenClipboard()
c = win32clipboard.GetClipboardData()
win32clipboard.EmptyClipboard()
c = c.replace('\n', ' ')
c = c.replace('\r', ' ')
while c.find('  ') != -1:
    c = c.replace('  ', ' ')
win32clipboard.SetClipboardText(c)
win32clipboard.CloseClipboard()

8

ไลบรารีมาตรฐาน python ทำได้ ...

try:
    # Python3
    import tkinter as tk
except ImportError:
    # Python2
    import Tkinter as tk

def getClipboardText():
    root = tk.Tk()
    # keep the window from showing
    root.withdraw()
    return root.clipboard_get()

4

ใช้ Pythons library Clipboard

ใช้เพียงแค่นี้:

import clipboard
clipboard.copy("this text is now in the clipboard")
print clipboard.paste()  

9
นี่คือการใช้ pyperclip เป็นหลัก from pyperclip import copy, pasteรหัสที่มาทั้งหมดของโมดูลนี้เป็นตัวอักษร:
pbreach

มันเป็นความจริง. อย่างไรก็ตามพวกเขาพูดถูกว่าclipboardเป็นชื่อที่ดีกว่า ฟังก์ชันนี้ควรรวมอยู่ในไลบรารีมาตรฐาน Python
Vincenzooo


3

สำหรับโปรแกรมคอนโซลของฉันคำตอบด้วย tkinter ด้านบนไม่ได้ผลสำหรับฉันเพราะ .destroy () ให้ข้อผิดพลาดเสมอ:

ไม่สามารถเรียกใช้คำสั่ง "เหตุการณ์": แอปพลิเคชันถูกทำลายขณะดำเนินการ ...

หรือเมื่อใช้. ถอน () หน้าต่างคอนโซลไม่ได้รับโฟกัสกลับมา

ในการแก้ปัญหานี้คุณต้องเรียก. update () ก่อน .destroy () ตัวอย่าง:

# Python 3
import tkinter

r = tkinter.Tk()
text = r.clipboard_get()
r.withdraw()
r.update()
r.destroy()

r.withdraw () ป้องกันไม่ให้เฟรมแสดงเป็นมิลลิวินาทีจากนั้นเฟรมจะถูกทำลายโดยให้โฟกัสกลับไปที่คอนโซล


1

เคล็ดลับที่ไม่ตรงมาก:

ใช้คีย์ลัด pyautogui:

Import pyautogui
pyautogui.hotkey('ctrl', 'v')

ดังนั้นคุณสามารถวางข้อมูลคลิปบอร์ดได้ตามต้องการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.