Como leio o texto da área de transferência (do Windows) em python?

92

Como leio o texto da área de transferência (do Windows) em python?

Foo42
fonte
3
Relacionado a esta questão .
glglgl de
no meu caso, apenas a resposta dan funcionou, que usa pacote de prancheta .
Soorena 09/10/2016

Respostas:

103

Você pode usar o módulo chamado win32clipboard , que faz parte do pywin32 .

Aqui está um exemplo que primeiro define os dados da área de transferência e depois os obtém:

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

Um lembrete importante da documentação:

Quando a janela terminar de examinar ou alterar a área de transferência, feche a área de transferência chamando CloseClipboard. Isso permite que outras janelas acessem a área de transferência. Não coloque um objeto na área de transferência após chamar CloseClipboard.

Sakin
fonte
6
Você sabe se existe uma maneira de usar a instrução `with´?
Norfeldt
3
Vale a pena observar, em py34, win7, SetClipboardText não funcionava sem uma chamada anterior para EmptyClipboard
CoderTao
Este módulo é útil se você deseja realizar operações mais complexas, por exemplo, obter o conteúdo formatado em HTML da área de transferência. Consulte stackoverflow.com/questions/17298897/…
xji
2
@Norfeldt Se não houver uma forma nativa, você pode criar facilmente seu próprio objeto personalizado que suporte "com"
Elijas
38

você pode fazer isso facilmente por meio do módulo integrado Tkinter, que é basicamente uma biblioteca GUI. Este código cria um widget em branco para obter o conteúdo da área de transferência do sistema operacional.

#from tkinter import Tk  # Python 3
from Tkinter import Tk
Tk().clipboard_get()
kmonsoor
fonte
2
Por favor, adicione comentários a este código e (possivelmente) links para documentação relevante.
jb.
5
deve ser em tkintervez de Tkinter. Caso contrário, não funcionou no meu win10 python 3.7.3 64 bits.
jerik
21

Já vi muitas sugestões para usar o módulo win32, mas o Tkinter fornece o método mais curto e fácil que já vi, como neste post: Como faço para copiar uma string para a área de transferência no Windows usando Python?

Além disso, o Tkinter está na biblioteca padrão do python.

Buttons840
fonte
3
Algum código que obterá o valor da área de transferência via Tkinter: do Tkinter import Tk [\ nl] r = Tk () [\ nl] result = r.selection_get (selection = "CLIPBOARD") [\ nl] r.destroy ()
mgkrebbs
18

Se você não quiser instalar pacotes extras, ctypespode fazer o trabalho também.

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())
Kichik
fonte
Isso parece não funcionar no Windows 10. Ele sempre imprime "Nenhum".
Aran-Fey
O Windows 10 funcionou bem para mim, desde que eu usasse o Python de 32 bits. Eu atualizei a resposta para trabalhar com 64 bits também.
kichik
vai este erro "ponteiro char esperado, obtido int" na linha "text = ctypes.c_char_p (data_locked)", alguma ideia?
txemsukr
Seria ótimo ver uma solução semelhante para copiar texto para a área de transferência também.
mrkbutty
11

A resposta mais votada acima é estranha de uma forma que simplesmente limpa a área de transferência e, em seguida, obtém o conteúdo (que fica vazio). Pode-se limpar a área de transferência para ter certeza de que algum tipo de conteúdo da área de transferência, como "texto formatado", não "cubra" o conteúdo de texto simples que você deseja salvar na área de transferência.

O seguinte trecho de código substitui todas as novas linhas na área de transferência por espaços, remove todos os espaços duplos e finalmente salva o conteúdo de volta na área de transferência:

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()
nascermos
fonte
11

Descobri que essa era a maneira mais fácil de acessar a área de transferência do python:

1) Instale o pyperclip: pip install pyperclip

2) Uso:

import pyperclip

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

# the type of s is string

Testado em Win10 de 64 bits, Python 3.5 e Python 3.7.3 (64 bits). Parece funcionar com caracteres não ASCII também. Os caracteres testados incluem ± ° ©| αβγθΔΨΦåäö

np8
fonte
é adequado para 3,6? ele foi instalado com sucesso, mas quando usado o método paste () me deu o erro: "da versão de importação do PySide como PYSIDE_VERSION # analysis: ignore ModuleNotFoundError: Nenhum módulo chamado 'PySide'". Quando tentei instalar o Pyside ele diz que não é compatível com o 3.6
gaurav
Sim, deve funcionar no Python 3.6 e acabei de testar com o Python 3.7.4 (64 bits). Olhando o setup.py do pacote, ele não deve ter dependências para Pyside ou qualquer outro pacote. Tem certeza de que o comando paste está tentando usar Pyside?
np8
Sim, o comando paste está procurando Pyside e como Pyside só é compatível com até python 3.4, ele dá erro
gaurav
7

A biblioteca padrão do python faz isso ...

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()
Paul Sumpner
fonte
3

Tente win32clipboard do pacote win32all (que provavelmente está instalado se você estiver no ActiveState Python).

Veja o exemplo aqui: http://code.activestate.com/recipes/474121/

Eli Bendersky
fonte
3

Para o meu programa de console, as respostas com tkinter acima não funcionaram muito bem para mim porque o .destroy () sempre deu um erro ,:

não é possível invocar o comando "evento": o aplicativo foi destruído durante a execução ...

ou ao usar .withdraw () a janela de console não recuperou o foco.

Para resolver isso, você também precisa chamar .update () antes de .destroy (). Exemplo:

# Python 3
import tkinter

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

O r.withdraw () evita que o quadro apareça por um milissegundo, e então será destruído devolvendo o foco ao console.

user136036
fonte
2

Use a biblioteca Pythons Clipboard

É simplesmente usado assim:

import clipboard
clipboard.copy("this text is now in the clipboard")
print clipboard.paste()  
Dan
fonte
8
Isso é essencialmente usando pyperclip. O código fonte inteira deste módulo é literalmente: from pyperclip import copy, paste.
pbreach de
1

Um truque não muito direto:

Use a tecla de atalho pyautogui:

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

Portanto, você pode colar os dados da área de transferência como desejar.

see2
fonte