Як прочитати текст з буфера обміну (windows) з python?


Відповіді:


104

Ви можете використовувати модуль під назвою 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`?
Норфельдт

3
Варто зазначити, що в py34, win7 SetClipboardText не працював без попереднього виклику EmptyClipboard
CoderTao

Цей модуль корисний, якщо ви хочете виконувати більш складні операції, наприклад, витягуючи вміст у форматі HTML із буфера обміну. Див stackoverflow.com/questions/17298897 / ...
xji

2
@Norfeldt Якщо немає рідного способу, ви можете легко створити власний власний об'єкт, що підтримує "за допомогою"
Elijas,

39

Ви можете легко зробити це за допомогою вбудованого модуля Tkinter, який в основному є бібліотекою графічного інтерфейсу. Цей код створює порожній віджет для отримання вмісту буфера обміну з ОС.

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

2
Будь ласка, додайте коментар до цього коду та (можливо) посилання на розкриту документацію.
jb.

6
має бути tkinterзамість Tkinter. В іншому випадку це не працювало на моєму python 3.7.3 64bit win10.
Джерік,

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".
Аран-Фей,

Windows 10 працював у мене нормально, поки я використовував 32-розрядний Python. Я також оновив відповідь для роботи з 64-розрядними версіями.
kichik

перейти до цієї помилки "очікуваний вказівник на символ, отриманий int" у рядку "text = ctypes.c_char_p (data_locked)", будь-яка ідея?
txemsukr

Було б чудово побачити подібне рішення для копіювання тексту в буфер обміну.
mrkbutty

14

Я з’ясував, що це найпростіший спосіб отримати доступ до буфера обміну з 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. Тестовані символи включають ± ° © © αβγθΔΨΦåäö


підходить для 3,6? він встановлений успішно, але при використанні методу paste () це видає мені помилку: "з версії імпорту PySide як PYSIDE_VERSION # аналіз: ігнорувати ModuleNotFoundError: Немає модуля з іменем" PySide "". Коли я намагався встановити Pyside, він каже, що це не підтримується в 3.6
gaurav

Так, це повинно працювати на Python 3.6, і я щойно тестував на Python 3.7.4 (64-розрядна версія). Дивлячись на setup.py пакета, він не повинен мати залежностей від Pyside чи будь-яких інших пакетів. Ви впевнені, що команда вставлення намагається використовувати 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()

7

Стандартна бібліотека 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()


3

Для моєї консольної програми відповіді з tkinter вище для мене не зовсім працювали, оскільки .destroy () завжди давав помилку:

не вдається викликати команду "event": додаток було знищено під час виконання ...

або при використанні .withdraw () вікно консолі не повернуло фокус назад.

Щоб вирішити це, вам також потрібно зателефонувати .update () перед .destroy (). Приклад:

# Python 3
import tkinter

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

R.withdraw () запобігає показу кадру протягом мілісекунди, а потім він буде знищений, віддаючи фокус консолі.


2

Використовуйте буфер обміну бібліотеки Pythons

Його просто використовують так:

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

8
По суті, це використання pyperclip. Весь вихідний код цього модуля буквально: from pyperclip import copy, paste.
зловживання

1

Не дуже прямий фокус:

Використовуйте гарячу клавішу pyautogui:

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

Тому ви можете вставити дані буфера обміну як завгодно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.