26

我正在考虑使用 Python 编写一个程序,该程序将找到一首我提供的歌曲的歌词。我认为整个过程应该归结为以下几件事。这些是我希望程序在运行时执行的操作:

  • 提示我输入歌曲名称
  • 复制那个名字
  • 打开网络浏览器(例如谷歌浏览器)
  • 将该名称粘贴到地址栏中并查找有关歌曲的信息
  • 打开包含歌词的页面
  • 复制那歌词
  • 运行文本编辑器(例如 Microsoft Word)
  • 粘贴歌词
  • 用歌曲名称保存新的文本文件

当然,我不是要代码。我只是想知道关于如何使用python与其他程序交互的概念或想法

更具体地说,我想我想知道,狐狸示例,我们如何指出 Google Chrome 中的地址栏在哪里,并告诉 python 将名称粘贴到那里。或者我们如何告诉 python 如何复制歌词并将其粘贴到 Microsof Word 的工作表中然后保存。

我一直在阅读(我还在阅读)几本关于 Python 的书:《Python 字节》、《艰难地学习 Python》、《Python for dummies》、《Beginning Game Development with Python and Pygame》。但是,我发现我似乎只(或几乎只)学习创建可自行运行的程序(我无法告诉我的程序使用已安装在我计算机上的其他程序执行我想做的事情)

我知道我的问题在某种程度上听起来很傻,但我真的很想知道它是如何工作的,我们告诉 Python regconize 谷歌 chrome 浏览器的这一部分是地址栏并且它应该将歌曲的名称粘贴到它。让 python 与另一个程序交互的整个想法对我来说真的很模糊,我只是非常想掌握这一点。

谢谢大家,谁花时间阅读我这么长的问题。

ttriet204

4

5 回答 5

42

如果您真正想要的是一个自学如何与其他应用程序交互的好借口,那么这可能不是最好的。Web 浏览器很混乱,时间无法预测,等等。所以,你已经承担了一项非常艰巨的任务——如果你按照通常的方式来做这件事会很容易(直接与服务器对话,创建文本文件直接等,都无需触及任何其他程序)。

但是,如果您确实想与其他应用程序交互,则有多种不同的方法,哪种方法合适取决于您需要处理的应用程序类型。

  • 一些应用程序旨在从外部实现自动化。在 Windows 上,这几乎总是意味着它们是一个 COM 接口,通常带有一个 IDispatch 接口,您可以为此使用pywin32的 COM 包装器;在 Mac 上,它表示一个 AppleEvent 接口,您可以使用ScriptingBridgeappscript; 在其他平台上没有通用标准。IE(但可能不是 Chrome)和 Word 都有这样的界面。

  • 一些应用程序有一个非 GUI 界面——无论是您可以使用的命令行popen,还是您可以通过ctypes. 或者,理想情况下,其他人已经为您编写了 Python 绑定。

  • 有些应用程序只有 GUI,而且没有办法实现 GUI 自动化。您可以在低级别执行此操作,方法是在 Windows 上制作 WM_ 消息以发送pywin32,使用 Mac 上的辅助功能 API 等,或者在更高级别使用库pywinauto,或者可能在非常高级别selenium或类似工具旨在自动化特定应用程序。

因此,您可以使用任何东西来做到这一点,从 Chrome 的 selenium 和 Word 的 COM 自动化,到自己制作所有 WM_ 消息。如果这是一个学习练习,那么问题是你今天想学习哪些东西。


让我们从 COM 自动化开始。使用pywin32,您可以直接访问应用程序自己的脚本界面,而无需从用户那里控制 GUI,弄清楚如何导航菜单和对话框等。这是编写“Word 宏”的现代版本——宏可以是外部脚本而不是 Word 内部,它们不必用 VB 编写,但它们看起来非常相似。脚本的最后一部分看起来像这样:

word = win32com.client.dispatch('Word.Application')
word.Visible = True
doc = word.Documents.Add()
doc.Selection.TypeText(my_string)
doc.SaveAs(r'C:\TestFiles\TestDoc.doc')

如果您查看Microsoft Word Scripts,您会看到一堆示例。但是,您可能会注意到它们是用 VBScript 编写的。如果您四处寻找教程,它们都是为 VBScript(或更旧的 VB)编写的。大多数应用程序的文档都是为 VBScript(或 VB、.NET,甚至低级 COM)编写的。以及我所知道的从 Python 中使用 COM 自动化的所有教程,例如客户端 COM 和 Python 的快速入门, 是为那些已经了解 COM 自动化的人编写的,并且只是想知道如何从 Python 中做到这一点。Microsoft 不断更改所有内容的名称这一事实使得搜索变得更加困难——您如何猜测在谷歌上搜索 OLE 自动化、ActiveX 脚本、Windows Scripting House 等与学习 COM 自动化有什么关系?所以,我不知道该推荐什么开始。我可以保证,一旦你学会了所有的废话,这一切就像上面那个例子看起来一样简单,但我不知道如何克服最初的障碍。

无论如何,并非每个应用程序都是可自动化的。有时,即使是这样,描述 GUI 操作(用户在屏幕上单击的内容)也比考虑应用程序的对象模型更简单。“选择第三段”很难用 GUI 术语来描述,但“选择整个文档”很容易——只需按 control-A,或转到“编辑”菜单并选择所有。GUI 自动化比 COM 自动化要困难得多,因为您要么必须向应用程序发送与 Windows 本身发送的相同消息以表示您的用户操作(例如,请参阅“菜单通知”),或者更糟糕的是,制作鼠标消息,如“go (32 , 4) 从左上角的像素点,单击,鼠标向下16个像素点,再次单击”表示“打开文件菜单,然后单击新建”。

幸运的是,有类似的工具pywinauto将这两种 GUI 自动化的东西都包起来,使它变得更简单。并且有类似的工具swapy可以帮助您确定要发送的命令。如果您不喜欢 Python,那么还有像AutoItandActions这样的工具,它们甚至比使用swapyand更容易pywinauto,至少在您开始使用时是这样。这样一来,脚本的最后一部分可能如下所示:

word.Activate()
word.MenuSelect('File->New')
word.KeyStrokes(my_string)
word.MenuSelect('File->Save As')
word.Dialogs[-1].FindTextField('Filename').Select()
word.KeyStrokes(r'C:\TestFiles\TestDoc.doc')
word.Dialogs[-1].FindButton('OK').Click()

最后,即使使用了所有这些工具,Web 浏览器也很难实现自动化,因为每个网页都有自己的菜单、按钮等,它们不是 Windows 控件,而是 HTML。除非你想一路下降到“将鼠标移动 12 像素”的水平,否则很难处理这些。这就是它的selenium用武之地——它编写 Web GUI 的方式与pywinauto编写 Windows GUI 的方式相同。

于 2013-01-11T23:32:24.300 回答
15

以下脚本使用Automa完全按照您的意愿进行操作(在 Word 2010 上测试):

def find_lyrics():
    print 'Please minimize all other open windows, then enter the song:'
    song = raw_input()
    start("Google Chrome")
    # Disable Google's autocompletion and set the language to English:
    google_address = 'google.com/webhp?complete=0&hl=en'
    write(google_address, into="Address")
    press(ENTER)
    write(song + ' lyrics filetype:txt')
    click("I'm Feeling Lucky")
    press(CTRL + 'a', CTRL + 'c')
    press(ALT + F4)
    start("Microsoft Word")
    press(CTRL + 'v')
    press(CTRL + 's')
    click("Desktop")
    write(song + ' lyrics', into="File name")
    click("Save")
    press(ALT + F4)
    print("\nThe lyrics have been saved in file '%s lyrics' "
          "on your desktop." % song)

要亲自尝试一下,请从其下载页面下载 Automa.zip,然后解压缩为c:\Program Files. 您将获得一个名为Automa 1.1.2. 在该文件夹中运行Automa.exe。复制上面的代码并通过右键单击控制台窗口将其粘贴到 Automa 中。按 Enter 两次以摆脱...窗口中的最后一个并返回提示符>>>。关闭所有其他打开的窗口并键入

>>> find_lyrics()

这将执行所需的步骤。

Automa是一个 Python 库:要这样使用它,您必须添加以下行

from automa.api import *

到你的脚本的顶部和library.zip从 Automa 的安装目录到你的环境变量的文件PYTHONPATH

如果您有任何其他问题,请告诉我:-)

于 2013-01-13T14:35:54.110 回答
12

这是@Matteo Italia 评论的 Python 实现:

当您应该从“程序员的角度”处理问题时,您是从“用户的角度”处理问题;你不需要打开浏览器、复制文本、打开 Word 或其他任何东西,你需要执行适当的 HTTP 请求、解析相关的 HTML、提取文本并将其从 Python 脚本中写入文件。执行此操作的所有工具都可以在 Python 中使用(特别是您需要 urllib2 和 BeautifulSoup)。

#!/usr/bin/env python
import codecs
import json
import sys
import urllib
import urllib2

import bs4  # pip install beautifulsoup4

def extract_lyrics(page):
    """Extract lyrics text from given lyrics.wikia.com html page."""
    soup = bs4.BeautifulSoup(page)
    result = []
    for tag in soup.find('div', 'lyricbox'):
        if isinstance(tag, bs4.NavigableString):
            if not isinstance(tag, bs4.element.Comment):
                result.append(tag)
        elif tag.name == 'br':
            result.append('\n')
    return "".join(result)

# get artist, song to search
artist = raw_input("Enter artist:")
song = raw_input("Enter song:")

# make request
query = urllib.urlencode(dict(artist=artist, song=song, fmt="realjson"))
response = urllib2.urlopen("http://lyrics.wikia.com/api.php?" + query)
data = json.load(response)

if data['lyrics'] != 'Not found':
    # print short lyrics
    print(data['lyrics'])
    # get full lyrics
    lyrics = extract_lyrics(urllib2.urlopen(data['url']))
    # save to file
    filename = "[%s] [%s] lyrics.txt" % (data['artist'], data['song'])
    with codecs.open(filename, 'w', encoding='utf-8') as output_file:
        output_file.write(lyrics)
    print("written '%s'" % filename)
else:
    sys.exit('not found')

例子

$ printf "Queen\nWe are the Champions" | python get-lyrics.py 

输出

我已经支付了会费
一次又一次
我已经完成了我的句子
但没有犯罪

和糟糕的错误
我做了几个
我的那份沙子被踢了 [...]
写“[女王] [我们是冠军]歌词.txt”
于 2013-01-15T12:42:48.160 回答
5

如果您真的想打开浏览器等,请查看selenium。但这对于您的目的来说太过分了。Selenium 用于模拟按钮点击等,用于测试网站在各种浏览器上的外观等。Mechanize对此并没有太大的杀伤力

您真正想要做的是了解浏览器(或任何其他程序)如何在幕后工作,即当您单击鼠标或在键盘上键入或点击Save时,程序在幕后做了什么?您希望 Python 代码执行的正是这些幕后工作。

所以,使用urllib, urllib2or requests(或者见鬼,甚至scrapy)来请求一个网页(学习如何将 url 放在一起谷歌搜索或GET歌词网站的 php 请求)。Google 还有一个搜索 API,您可以利用它来执行 google 搜索。

xml从页面请求中获得结果后,使用、beautifulsoup、等对其进行解析lxlml,并找到包含您所追求信息的请求结果部分。

现在您有了歌词,最简单的做法是打开一个文本文件并将歌词转储到其中并写入磁盘。但是如果你真的想用 MS Word 来做,那么doc在记事本或记事本++中打开一个文件并查看它的结构。现在,使用python构建一个类似结构的文档,其中内容将是下载的歌词。
如果此方法失败,您可以查看pywinauto等自动将文本粘贴到 MS Word 文档中并单击Save

引用:Matteo Italia,来自 OP 评论的 gddc

于 2013-01-11T23:28:58.233 回答
1

您应该查看一个selenium用于与 Web 浏览器交互的包

于 2013-01-11T23:16:20.130 回答