美文网首页大数据 爬虫Python AI SqlPython小哥哥
Python真神奇,带你体验另类的“全自动编程”

Python真神奇,带你体验另类的“全自动编程”

作者: 14e61d025165 | 来源:发表于2019-07-17 15:09 被阅读1次

近年来“自动编程”、“智能编程”方面的项目层出不穷,例如AutoML、kite,以及最近风靡一时的python_autocomplete,这些项目有一个共同点,就是基于机器学习模型,致力于提升代码补全和自动生成水平。

不过今天要展示的自动编程与上述概念不同,这次我们不讲学术、不论实用,抱着娱乐的心态体验一把另类的“全自动编程”模式。

Python资源共享群:484031800

<tt-image data-tteditor-tag="tteditorTag" contenteditable="false" class="syl1563347327259 ql-align-center" data-render-status="finished" data-syl-blot="image" style="box-sizing: border-box; cursor: text; text-align: left; color: rgb(34, 34, 34); font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", "Helvetica Neue", Arial, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial; display: block;"> image

<input class="pgc-img-caption-ipt" placeholder="图片描述(最多50字)" value="" style="box-sizing: border-box; outline: 0px; color: rgb(102, 102, 102); position: absolute; left: 187.5px; transform: translateX(-50%); padding: 6px 7px; max-width: 100%; width: 375px; text-align: center; cursor: text; font-size: 12px; line-height: 1.5; background-color: rgb(255, 255, 255); background-image: none; border: 0px solid rgb(217, 217, 217); border-radius: 4px; transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) 0s;"></tt-image>

01.

项目介绍

今天要介绍的这个库的名字叫pynput,与人工智能无关,这是一个控制和监控计算机输入设备的库,这是他的GitHub地址(详细见文末),从库的简介中可以看到,目前仅支持鼠标和键盘两种基本的输入设备。

<tt-image data-tteditor-tag="tteditorTag" contenteditable="false" class="syl1563347327264" data-render-status="finished" data-syl-blot="image" style="box-sizing: border-box; cursor: text; color: rgb(34, 34, 34); font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", "Helvetica Neue", Arial, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial; display: block;"> image

<input class="pgc-img-caption-ipt" placeholder="图片描述(最多50字)" value="" style="box-sizing: border-box; outline: 0px; color: rgb(102, 102, 102); position: absolute; left: 187.5px; transform: translateX(-50%); padding: 6px 7px; max-width: 100%; width: 375px; text-align: center; cursor: text; font-size: 12px; line-height: 1.5; background-color: rgb(255, 255, 255); background-image: none; border: 0px solid rgb(217, 217, 217); border-radius: 4px; transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) 0s;"></tt-image>

接下来我们打开文档,看看pynput究竟有哪些功能。从文档目录(下图)来看,关于pynput的说明大体分为三个部分:分别是鼠标事件、键盘事件和平台限制

先来简单说一下平台限制,因为事关外部输入设备,在不同的操作系统中肯定会有一些差异和功能限制,例如Linux下需要设置环境变量$ DISPLAY、MAC操作系统限制了对键盘的监控、Windows中进程间的虚拟事件传递可能受限等等。

总的来说,平台限制并不影响基本的使用(特别是在Windows系统中),我们暂且放下不谈。

<tt-image data-tteditor-tag="tteditorTag" contenteditable="false" class="syl1563347327272" data-render-status="finished" data-syl-blot="image" style="box-sizing: border-box; cursor: text; color: rgb(34, 34, 34); font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", "Helvetica Neue", Arial, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial; display: block;"> image

<input class="pgc-img-caption-ipt" placeholder="图片描述(最多50字)" value="" style="box-sizing: border-box; outline: 0px; color: rgb(102, 102, 102); position: absolute; left: 187.5px; transform: translateX(-50%); padding: 6px 7px; max-width: 100%; width: 375px; text-align: center; cursor: text; font-size: 12px; line-height: 1.5; background-color: rgb(255, 255, 255); background-image: none; border: 0px solid rgb(217, 217, 217); border-radius: 4px; transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) 0s;"></tt-image>

接着我们重点聊一聊鼠标事件和键盘事件。先来说鼠标事件部分,pynput对鼠标事件的处理主要分为控制和监控两大部分。

在鼠标控制部分,可以通过代码模拟鼠标的移动、单击、双击、滚轮等操作,下面这张图就是文档中的演示代码,函数名称和实际事件名基本一致,很容易理解。

<tt-image data-tteditor-tag="tteditorTag" contenteditable="false" class="syl1563347327278" data-render-status="finished" data-syl-blot="image" style="box-sizing: border-box; cursor: text; color: rgb(34, 34, 34); font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", "Helvetica Neue", Arial, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial; display: block;"> image

<input class="pgc-img-caption-ipt" placeholder="图片描述(最多50字)" value="" style="box-sizing: border-box; outline: 0px; color: rgb(102, 102, 102); position: absolute; left: 187.5px; transform: translateX(-50%); padding: 6px 7px; max-width: 100%; width: 375px; text-align: center; cursor: text; font-size: 12px; line-height: 1.5; background-color: rgb(255, 255, 255); background-image: none; border: 0px solid rgb(217, 217, 217); border-radius: 4px; transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) 0s;"></tt-image>

在鼠标事件的监控部分,监控任务Listener实际上是一个threading.Thread对象,采用回调函数的方式实时监控鼠标行为(下图是文档中的演示代码)。既然是threading.Thread对象,Listener当然也就有阻塞和非阻塞两种模式,一般来说,如果想要监控物理鼠标的行为,使用阻塞模式比较合适,如果想要监控pynput的模拟鼠标操作,建议采用非阻塞模式。

<tt-image data-tteditor-tag="tteditorTag" contenteditable="false" class="syl1563347327282" data-render-status="finished" data-syl-blot="image" style="box-sizing: border-box; cursor: text; color: rgb(34, 34, 34); font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", "Helvetica Neue", Arial, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial; display: block;"> image

<input class="pgc-img-caption-ipt" placeholder="图片描述(最多50字)" value="" style="box-sizing: border-box; outline: 0px; color: rgb(102, 102, 102); position: absolute; left: 187.5px; transform: translateX(-50%); padding: 6px 7px; max-width: 100%; width: 375px; text-align: center; cursor: text; font-size: 12px; line-height: 1.5; background-color: rgb(255, 255, 255); background-image: none; border: 0px solid rgb(217, 217, 217); border-radius: 4px; transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) 0s;"></tt-image>

再来看键盘事件部分,和鼠标事件类似,pynput对键盘事件的处理也是分为控制和监控两大部分,函数结构和操作模式也跟鼠标事件基本相同,这里就不展示文档中的演示代码了。有一点需要注意的是,键盘操作中有一些特殊方法,比如“ctrl+”、‘“shift+”、“alt+”这类的组合键,还有F1~FN、backspace、delete、insert等特殊功能键,在pynput中都有专门的定义,在操作时可以直接使用。

02.

功能演示

介绍完基本功能,我们就写一段代码试一试pynput的设备控制以及监控效果,由于上文中重点介绍了关于鼠标事件的处理,这里就以键盘事件处理为例进行演示。

我们设计这样一个程序:

  • 主线程:随机生成20个(准确地说是19个)小写英文字母,并用pynput模拟键盘输入,在第10个字母输入后附加输入一个退格键(backspace)。
  • 监控线程:对键盘的按键和松开两种操作进行监控,同时在控制台输出相关信息,当遇到退格键(backspace)松开这一事件时,终止监控线程。

为了便于观察,在每个随机字符串输入后加入一个0.5s的时间间隔,另外由于这里是要监控虚拟的键盘按键事件,因此监控线程使用非阻塞模式,代码如下:

<tt-image data-tteditor-tag="tteditorTag" contenteditable="false" class="syl1563347327289" data-render-status="finished" data-syl-blot="image" style="box-sizing: border-box; cursor: text; color: rgb(34, 34, 34); font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", "Helvetica Neue", Arial, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial; display: block;"> image

<input class="pgc-img-caption-ipt" placeholder="图片描述(最多50字)" value="" style="box-sizing: border-box; outline: 0px; color: rgb(102, 102, 102); position: absolute; left: 187.5px; transform: translateX(-50%); padding: 6px 7px; max-width: 100%; width: 375px; text-align: center; cursor: text; font-size: 12px; line-height: 1.5; background-color: rgb(255, 255, 255); background-image: none; border: 0px solid rgb(217, 217, 217); border-radius: 4px; transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) 0s;"></tt-image>

一起来看下这段代码的动态执行情况,在下面这段动画中字符(包括退格键)的输入全部都是基于pynput自动实现的。

<tt-image data-tteditor-tag="tteditorTag" contenteditable="false" class="syl1563347327294" data-render-status="finished" data-syl-blot="image" style="box-sizing: border-box; cursor: text; color: rgb(34, 34, 34); font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", "Helvetica Neue", Arial, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial; display: block;"> image

<input class="pgc-img-caption-ipt" placeholder="图片描述(最多50字)" value="" style="box-sizing: border-box; outline: 0px; color: rgb(102, 102, 102); position: absolute; left: 187.5px; transform: translateX(-50%); padding: 6px 7px; max-width: 100%; width: 375px; text-align: center; cursor: text; font-size: 12px; line-height: 1.5; background-color: rgb(255, 255, 255); background-image: none; border: 0px solid rgb(217, 217, 217); border-radius: 4px; transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) 0s;"></tt-image>

(动态图,盯着看几秒哦)

通过上面这个动画可以看到,在程序运行的前半部分,输入结果和监控结果是完全一致的,直到退格键(backspace)事件发生后,控制台就不再输出监控信息,这是因为监控线程已经被终止掉了,但是模拟键盘输入仍然会继续,直到指定数量的字符串全部输入完毕为止。通过这个例子应该就能很好地理解pynput的监控线程了,有兴趣的朋友不妨自己体会一下。

至于鼠标事件的控制、监控功能,因为和键盘事件十分类似,这里就不再重复演示了。另外,由于鼠标没有键盘中那么多复杂的、各式各样的功能键,从某种意义上说鼠标事件的处理要比键盘事件处理更简单一些。

03.

神奇的"自动编程"

最后,我们回到今天的主题,把鼠标事件和键盘事件的控制结合起来,实现一个“全自动编程”的功能。事实上这里实现的“自动编程”与人工智能无关,也不是传统的代码匹配补全,而是控制鼠标和键盘按照我们提前设置好的步骤自动运行。

为了方便,我们就用最简单的“Hello World”来进行演示,在sublime中完成“Hello World”程序大概需要经过以下几个步骤:新建一个sublime文件——命名、保存为py文件——在新建的py文件中输入“print('Hello World')”语句——再次保存——运行新的程序。

前文讲到过,pynput可以模拟所有的鼠标和键盘操作,上面步骤中的操作自然也可以由pynput模拟完成,就跟手动操作一样。我们把以上操作全部写到脚本中,同时加入鼠标和键盘的监控线程,在脚本启动后不仅会自动编写运行“Hello World”程序,还会对鼠标和键盘的模拟操作进行实时监控,并将相关信息输出到控制台。

先来看结果,下面这个动画就是我们写的“自动编程”脚本的运行情况,整个过程全部自动执行,没有任何手动干预。

<tt-image data-tteditor-tag="tteditorTag" contenteditable="false" class="syl1563347327303 ql-align-center" data-render-status="finished" data-syl-blot="image" style="box-sizing: border-box; cursor: text; text-align: left; color: rgb(34, 34, 34); font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", "Helvetica Neue", Arial, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial; display: block;"> image

<input class="pgc-img-caption-ipt" placeholder="图片描述(最多50字)" value="" style="box-sizing: border-box; outline: 0px; color: rgb(102, 102, 102); position: absolute; left: 187.5px; transform: translateX(-50%); padding: 6px 7px; max-width: 100%; width: 375px; text-align: center; cursor: text; font-size: 12px; line-height: 1.5; background-color: rgb(255, 255, 255); background-image: none; border: 0px solid rgb(217, 217, 217); border-radius: 4px; transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) 0s;"></tt-image>

(动态图,盯着看几秒哦)

在整个过程中,所有的鼠标和键盘事件都会被监控线程记录,包括每一次键盘按键的点击和释放、鼠标的移动和点击等。

下面我们来看看这个脚本的核心代码,可以看到,我们使用pynput模拟了所有与鼠标和键盘有关的操作,使用这种方法还可以编写更加复杂的程序,只需要改变keycontroller.type的输入内容就可以

<pre spellcheck="false" style="box-sizing: border-box; margin: 5px 0px; padding: 5px 10px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: 400; font-stretch: inherit; font-size: 16px; line-height: inherit; font-family: inherit; vertical-align: baseline; cursor: text; counter-reset: list-1 0 list-2 0 list-3 0 list-4 0 list-5 0 list-6 0 list-7 0 list-8 0 list-9 0; background-color: rgb(240, 240, 240); border-radius: 3px; white-space: pre-wrap; color: rgb(34, 34, 34); letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">keycontroller = keyboard.Controller()
mousecontroller = mouse.Controller()

新建文件

keycontroller.press(keyboard.Key.ctrl_l)
keycontroller.press('n')
keycontroller.release(keyboard.Key.ctrl_l)
keycontroller.release('n')
sleep(1)

保存文件

keycontroller.press(keyboard.Key.ctrl_l)
keycontroller.press('s')
keycontroller.release(keyboard.Key.ctrl_l)
keycontroller.release('s')
sleep(1)

输入文件名称

keycontroller.type('auto{}.py'.format(random.uniform(0,99)))
sleep(1)

点击保存

mousecontroller.position = (0, 0)
mousecontroller.move(466, 493)
mousecontroller.press(mouse.Button.left)
mousecontroller.release(mouse.Button.left)
sleep(1)

输入代码

keycontroller.type("print('Hello World')")
keycontroller.press(keyboard.Key.space)
sleep(1)

重新保存

keycontroller.press(keyboard.Key.ctrl_l)
keycontroller.press('s')
keycontroller.release(keyboard.Key.ctrl_l)
keycontroller.release('s')
sleep(1)

运行新程序

keycontroller.press(keyboard.Key.ctrl_l)
keycontroller.press('b')
keycontroller.release(keyboard.Key.ctrl_l)
keycontroller.release('b')
</pre>

(代码可以左右滑动)

友情提示

正如本文开头所说,使用pynput实现的所谓“自动编程”仅仅是一种娱乐,并没有太多实用价值。但是pynput对于输入设备的控制和监控在实践中倒是有可能会用得上,至于如何发挥他的作用,就要看自己的想象力了。

相关文章

网友评论

    本文标题:Python真神奇,带你体验另类的“全自动编程”

    本文链接:https://www.haomeiwen.com/subject/jigqlctx.html