Как мне прочитать текст из буфера обмена (windows) из Python?

Ответы:

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»
Элияс Дапшаускас
42

вы можете легко сделать это с помощью встроенного модуля Tkinter, который в основном представляет собой библиотеку графического интерфейса. Этот код создает пустой виджет для получения содержимого буфера обмена из ОС.

#from tkinter import Tk  # Python 3
from Tkinter import Tk
Tk().clipboard_get()
kmonsoor
источник
2
Пожалуйста, добавьте комментарий к этому коду и (возможно) ссылки на полезную документацию.
jb.
7
должно быть tkinterвместо Tkinter. В противном случае это не сработало на моем python 3.7.3 64bit win10.
jerik
21

Я видел много предложений по использованию модуля win32, но Tkinter предоставляет самый короткий и простой метод, который я видел, как в этом посте: Как скопировать строку в буфер обмена в Windows с помощью Python?

Кроме того, Tkinter входит в стандартную библиотеку Python.

Кнопки840
источник
3
Некоторый код, который получит значение буфера обмена через Tkinter: from Tkinter import Tk [\ nl] r = Tk () [\ nl] result = r.selection_get (selection = "CLIPBOARD") [\ nl] r.destroy ()
mgkrebbs 08
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. Он всегда печатает «Нет».
Аран-Фей
Windows 10 отлично работала у меня, пока я использовал 32-разрядную версию Python. Я обновил ответ для работы с 64-битной версией.
kichik 02
перейти к этой ошибке "ожидаемый указатель char, получил int" в строке "text = ctypes.c_char_p (data_locked)", любая идея?
txemsukr 08
1
Было бы здорово увидеть подобное решение и для копирования текста в буфер обмена.
mrkbutty
18

Я выяснил, что это самый простой способ получить доступ к буферу обмена из python:

1) Установите pyperclip: pip install pyperclip

2) Использование:

import pyperclip

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

# the type of s is string

Проверено на 64-разрядной версии Win10, Python 3.5 и Python 3.7.3 (64-разрядной версии). Кажется, работает и с символами, отличными от ASCII. Протестированные символы включают ± ° © © αβγθΔΨΦåäö

np8
источник
на 3.6 подходит? он установлен успешно, но при использовании метода paste () он дает мне ошибку: «из версии импорта PySide как PYSIDE_VERSION # analysis: ignore ModuleNotFoundError: No module named 'PySide'». Когда я пытался установить Pyside, он говорит, что он не поддерживается в 3.6
gaurav
Да, он должен работать на Python 3.6, и я только что тестировал Python 3.7.4 (64-разрядный). Если посмотреть на пакет setup.py , он не должен иметь зависимостей от Pyside или любых других пакетов. Вы уверены, что команда вставки пытается использовать Pyside?
np8
Да, команда paste ищет 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

Его просто используют так:

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 () всегда выдает ошибку:

невозможно вызвать команду "событие": приложение было уничтожено во время выполнения ...

или при использовании .withdraw () окно консоли не вернуло фокус.

Чтобы решить эту проблему, вам также необходимо вызвать .update () перед .destroy (). Пример:

# Python 3
import tkinter

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

R.withdraw () предотвращает отображение кадра в течение миллисекунды, а затем он будет уничтожен, возвращая фокус обратно на консоль.

user136036
источник
1

Не очень прямая уловка:

Используйте горячую клавишу pyautogui:

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

Таким образом, вы можете вставлять данные из буфера обмена по своему усмотрению.

см2
источник