使用一个Python脚本从Linux、Mac和Windows系统的剪贴板复制数据。

4
我试图用Python编写一个脚本,可以收集用户复制到剪贴板中的数据,并最好将其保存为列表或文本文件或字符串/数组/变量以供稍后使用。
这应该适用于所有版本的Linux(我认为包括Ubuntu),所有版本的Mac OS和所有版本的Windows。我不确定32位和64位系统是否有不同的访问剪贴板数据的方法,如果有,我想仅使其适用于32位版本,因此运行64位版本的人可以退回到操作系统的32位版本。
除了必须在提到的操作系统上工作之外,棘手的部分是,我希望脚本在用户不停止它的情况下运行,并且当它运行时,用户复制到剪贴板中的所有数据都被复制到列表或文本文件或字符串/数组/变量中。
当然,用户可以在剪贴板中输入数据的时间限制,所以我考虑每秒或每500毫秒循环扫描剪贴板,检查内容是否已更改,如果已更改,则复制它,否则不复制。
是否有一种统一的方式或模块可以在所有不同的操作系统上完成这项工作,还是最好为此任务编写各自的脚本以适用于各个操作系统?
问题是,这是一个更大项目的一部分,我希望在Linux,Mac和Windows上使其工作,因此覆盖这三个选项,然后使用可用于其他操作系统的Python代码对脚本/项目的其余部分进行操作将是理想的。总体而言,关于在Linux,Mac和Windows上运行,我对这个脚本要求太多了吗?

首先,不是所有的Linux都有剪贴板。 - orlp
5个回答

4

如果涉及到IT技术相关内容,建议您使用更高级的GUI工具包,而非Tk。但是Tk工具包是标准库的一部分,因此可以在任何地方使用。

以下是一个非常简单的示例:

import Tkinter
root = Tkinter.Tk()
root.withdraw() # Hide the main window (optional)
text_in_clipboard = root.clipboard_get()
print text_in_clipboard

这个例子在所有提到的操作系统上都能工作吗?由于@phihag提到Linux上可能有多个剪贴板,因此最好先专注于Windows剪贴板,然后再将其移植到Mac和Linux上,在那里用户会在脚本的每个新循环中复制和粘贴URL(a)。虽然希望避免这种情况,只需通过单击鼠标按钮即可选择URL(a)。 - lowtechsun
对于大多数应用程序来说,在第一个版本中,您可以安全地忽略 Linux 上的“遗留”剪贴板,只需使用称为“剪贴板”的 Ctrl-C/Ctrl-V 即可。我怀疑那些非常关心“主要”和“次要”剪贴板的人与那些会使用自动化 GUI 下载器的人之间没有重叠。 - millimoose
@Inerdia 对不起,什么是Linux上的遗留、主要和次要剪贴板?您是否在说在Linux上,用户可以使用任何浏览器浏览到包含URL的页面,例如用鼠标右键选择它们并复制链接位置,这样做就像在Mac或Windows上一样容易,并且比自己复制和粘贴URL到脚本/GUI中更受欢迎,需要按键吗?我认为有时同步剪贴板可能会擦除内容,这不是phihag所暗示的吗?我可以在哪个好的论坛上学习这个或者建立一个公共项目组来学习这个? - lowtechsun
@lowtechsun,所谓“legacy”剪贴板,我指的是“primary”和“secondary”,因为它们大多被旧应用程序使用。你可能需要在SO上搜索,看看是否有另一个问题解释了不同的Linux剪贴板之间的区别,如果没有的话就提问一个。此外,我也不知道你假想的用户受众会更喜欢哪种方式。 - millimoose
@Inerdia 是的,谢谢,我已经找到了PyGTKPyQt。只是不明白你所说的“关心‘主’和‘次’剪贴板的人和使用自动化GUI下载器的人之间是否有显著的重叠”。我正在搜索中。非常感谢所有用户迄今为止对这个问题的回复。谢谢! - lowtechsun
@lowtechsun 这个说法源于我的(很可能错误的)观点,即大多数现代 Linux GUI 应用程序专门使用 “clipboard” 剪贴板;如果有选项使它们使用旧的 X11 选择复制机制,则这不是那种会从现成 CD 安装 Ubuntu 并感到满意的 Linux 用户会打开的东西。 - millimoose

4

xerox库支持Linux、Mac OS X和Windows操作系统。

请注意,在短时间(小于1分钟)内执行任何操作都是非常不好的,因为这会使现代处理器定期唤醒。您可以使用相应操作系统的API来注册回调函数,一旦剪贴板发生变化就会被调用。


那么 xerox.copy(u) 会将任何在所列操作系统的剪贴板中的内容复制到我分配的变量中?对我来说,作为一个刚开始学习 Python 的人,似乎我可以使用 xerox 来复制和粘贴我在脚本中分配的字符串,而不是将实际在剪贴板中的内容作为脚本中的用户输入变量。这是正确的吗? - lowtechsun
@lowtechsun 是的,只需读取 sys.platform 并根据其确定要采取哪个分支。xerox 只会读取当前剪贴板,无论是谁设置的。请注意,在Unix系统(尤其是Linux)上可能有多个剪贴板。 - phihag
@lowtechsun,Xerox只使用X剪贴板(通过简单选择任何内容自动更新,并使用第三个鼠标按钮粘贴)。在许多Linux系统上有一个单独的(有时同步的)freedesktop.org剪贴板,具有完全不同的机制(Ctrl+C复制,Ctrl+V粘贴)。 - phihag
@lowtechsun 那篇文章提供了不错的指针,但我不建议在OS X上使用Carbon。Carbon已被弃用,没有32位版本。这意味着它在64位版本的Python 2.x上无法工作-而Lion上的默认Python是64位的。Carbon绑定也已从Python 3.x中删除。请不要使用Carbon。 - millimoose
@lowtechsun 在 OS X 上你可以使用 pyobjc 和 pasteboard api,我会在我的回答中添加一个代码示例。 - millimoose
显示剩余5条评论

2
您可以使用GUI工具包,例如Qt来获取可移植的剪贴板API。但是,仅为此目的使用整个GUI工具包可能有些过度杀菌。(当然,除非您还要用它来制作GUI。)
话虽如此,处理纯文本的剪贴板API应该相对简单,可以自己进行抽象。
例如,在OS X上,您可以使用PyObjC(与OS X一起安装)来获取剪贴板的纯文本内容:
from AppKit import NSPasteboard
from LaunchServices import 
pb = NSPasteboard.generalPasteboard()
text = pb.stringForType_(kUTTypeUTF8PlainText)

CPU 架构

在 64 位操作系统上的 32 位本机应用程序将访问与 64 位应用程序相同的剪贴板。如果您需要支持操作系统的两种架构,并且不编写驱动程序,在 Windows 上可以发布 32 位二进制文件;在 Linux 上,您可能需要做两个版本;对于 OS X,发布 64 位版本应该是相当安全的,自从 Leopard 以来,所有自 2007 年中期以来的 Mac 都配备了 64 位 CPU,并且有相应的操作系统支持。在 Linux 上,Python 脚本可能会由发行版软件包管理器中的 Python 安装执行,其位数将与系统匹配,因此您不必担心这个问题。


我正在学习Python的书籍使用Tk-Interface,我能用它作为例子吗?剪贴板上的数据将只有URL链接。我正在编写一个下载器。它从用户输入中获取URL(a),并根据一组模式更改它。然后它进入到创建的新URL(ab)中,例如这个网址,并将所有内容复制到剪贴板中,提取URL链接,检查是否存在404错误,并将良好的URL链接显示在列表中供用户查看。 - lowtechsun
关于32/64位操作系统: 所以,根据这个简短的基本概念,我认为只需要编写所有操作系统的32位版本才是真正需要的,对吧?我的意思是,在64位Linux上运行脚本的32位版本,是否可以呢?同样的,在Windows和Mac上,如果它们正在运行着一个63位的操作系统,它们仍然可以运行32位的脚本,对吧?现在有点困惑了。关于剪贴板: 我希望使用户尽可能轻松地输入URL(a),所以不要复制和粘贴到脚本中,而是从剪贴板中读取,而不是访问浏览器选项卡等等,对吧? - lowtechsun
@lowtechsun:Tk似乎具有某种基本的剪贴板功能。文档没有提到它是否与本地剪贴板集成;在当今这个时代,人们希望它能够实现本地集成,但历史上Tk并不擅长本地集成。 - millimoose
@lowtechsun,32/64位只在您编写本地代码以与剪贴板进行交互时才相关。如果您使用Tk或其他工具与操作系统进行交互,只需让库来操心即可。Python是一种脚本语言,在Python代码中不需要关注架构。 - millimoose
如果你想与网络浏览器进行交互,你应该编写一个浏览器扩展。你可以通过让Python脚本暴露一个Web服务并通过AJAX从扩展中调用它来使其与在后台运行的Python进程通信。 - millimoose
脚本只有在下载URL(ab)内容以及稍后的活动文件时才从Web获取数据。来自用户的原始URL(a)也可以由用户直接输入,而不是从剪贴板中读取。鉴于我刚开始学习Python,AJAX可能太多了,对吧?我发现,如果人们无需在所有操作系统上安装Firefox,即使只运行Safari,他们也可以使用某些东西,这样更加开放。只是个例子。尽可能开放,使其在所有操作系统上运行,无论浏览器如何。你觉得呢? - lowtechsun

2

轮询不是很健壮/可靠。

在Windows上,您无法确定数据是否已更改,除非将其粘贴到缓冲区进行检查。这需要打开剪贴板。如果您在循环中执行此操作,则会与其他应用程序发生冲突。即用户正在将另一个项目复制到剪贴板的应用程序。这将出现“无法打开剪贴板”或“内存不足”错误。这种方法不能可靠地工作。您需要在各个平台上使用正确的剪贴板监视API。


谢谢Chris提供的信息丰富的回复。那么,假设我有一个循环,在其中访问剪贴板并检查内容,如果内容更改,则将新内容复制到我分配的变量中,如果内容相同,则保持不变,在Windows上无法工作吗?我想使用剪贴板的唯一原因是让用户不必手动复制和粘贴URL。如果有更优雅的方法,比如用鼠标将URL简单地复制并粘贴为用户输入到脚本中,请告诉我。我看了你的网站,你似乎真的很懂剪贴板。谢谢! - lowtechsun

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接