初学者 AppleScript Writer 遇到空闲处理程序问题 [英] Beginner AppleScript Writer having trouble with idle handler

查看:22
本文介绍了初学者 AppleScript Writer 遇到空闲处理程序问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近一直在探索编码,我真的很喜欢解决问题.我现在对 AppleScript 感到很舒服,我认为它是我将来想用编码做的事情的一个不错的选择.我的直觉告诉我,Automator 在 RAM 方面的效率会更低,而且我不喜欢它的分割方式;以约束和混淆.我喜欢脚本语言的沙箱功能.我为一个网络爬虫构建了一个非常好的脚本,它打开一个在线股票投资组合并修剪加密货币的市场价格.我计划利用技术决策实验室来创建一个加密货币预测工作簿,以实现我有朝一日能赚钱的希望和梦想:[我梦想着制作一个实时 excel 文件,该文件构建交易每小时波动的图表.

为了使它成为一个成熟的自动化系统,我需要某种方式来循环脚本或安排它按计划运行,以便为我希望从数据中制定的数学模型获取大量数据点.我已经尝试真的努力使空闲处理程序工作,但它只是不像教程描述的那样运行.看来你不能使用空闲"使用某些命令,我​​每次使用该东西时都会收到错误消息.我找到了一个帮助页面,其中显示了如何合并哔"声.函数以确保空闲循环正在运行,并且当我编译并保存为始终运行的应用程序"时它不播放哔哔声,所以我想这是我还没有弄清楚的另一个问题.有时我会听到哔哔声,但现在我的程序最终草案无法正常工作.我曾尝试在 tell 语句中非常小心地插入它,因为我发现它有时适用于它们.我猜你不能让空闲处理程序跨越整个脚本;它需要在一个命令结构树中调用才能工作.但是我仍然没有让应用程序从空闲状态运行脚本以及我为研究这个解决方案所做的所有工作.任何对空闲处理程序秘密保持沉默的人都可以尽最大努力向我解释脚本的内部工作原理,但我发现学习编码需要很长时间,因为它需要大量非常技术性的阅读很少有机会可以锻炼自己的学习能力.编码是大量重复的样板代码,我想我会用到目前为止所学的知识在白发苍苍的日子里努力编写代码.

但是,如果您可以使用这个问题来收集一些阅读材料,了解如何在一台可以很好地处理大多数计算负载的笔记本电脑的后台以 30 分钟的增量运行一个编写得相当好的脚本,那将不胜感激.我不反对 Automator;要想让它发挥作用,你必须知道所有的事情,这本身就很困难.正如我所说,有关空闲处理程序以及如何使其工作的任何信息都会有所帮助.此外,如果可以在 AppleScript 中编写代码以在 Microsoft Excel 中生成绘图,我喜欢为衬衫和谷歌制作模型.

我想我会分享我在过去几周的工作中所做的工作,这些内容值得研究目前在线免费提供的教程.非常感谢任何关于如何使我的剧本变得更好的批评或建议,如果我做得很好,我不介意你抢走你喜欢的东西.这是目前的网络爬行加密货币股票分析器.它遵循 3 种货币并将数据写入 excel 文件中的年、月、日和秒,以收集大量数据以构建更强大的数学模型.我研究了将季节性应用于数据的技术预测技术,因此预测比仅使用 excel 中的趋势线函数要好,尽管由于加密货币的可变性,我不会对市场价格的长期预测加太多盐.我只想关注那些令人心痛的股票崩盘,以便有机会用我可以凑合起来维持生计的一点钱一瘸一拐地进入游戏.

--Boiler plate code来操作HTML让我们拉股票的市场价格.---- 3 种股票的 3 套修饰符--提取TextBitcoin(searchTextBitcoin, startTextBitcoin, endTextBitcoin)将 tid 设置为 AppleScript 的文本项分隔符将 startTextBitcoin 设置为>";将 searchTextBitcoin 设置为 {priceValue___11gHJ", 0 &搜索文本比特币}将 AppleScript 的文本项分隔符设置为 startTextBitcoin将 endItemsBitcoin 设置为 searchTextBitcoin 的文本项 -1将 AppleScript 的文本项分隔符设置为 endTextBitcoin将 beginToEndBitcoin 设置为 endItemsBitcoin 的文本项 1将 AppleScript 的文本项分隔符设置为 startTextBitcoin将 endTextBitcoin 设置为(beginningToEndBitcoin 的文本项 2 到 -1)作为记录将 AppleScript 的文本项分隔符设置为 tid结束提取文本比特币提取TextLitecoin(searchTextLitecoin,startTextLitecoin,endTextLitecoin)将 tid 设置为 AppleScript 的文本项分隔符将 startTextLitecoin 设置为>";将 searchTextLitecoin 设置为 {priceValue___11gHJ", 0 &搜索文本莱特币}将 AppleScript 的文本项分隔符设置为 startTextLitecoin将 endItemsLitecoin 设置为 searchTextLitecoin 的文本项 -1将 AppleScript 的文本项分隔符设置为 endTextLitecoin将 beginToEndLitecoin 设置为 endItemsLitecoin 的文本项 1将 AppleScript 的文本项分隔符设置为 startTextLitecoin将 endTextLitecoin 设置为(beginningToEndLitecoin 的文本项 2 到 -1)作为记录将 AppleScript 的文本项分隔符设置为 tid结束提取文本莱特币提取TextDogecoin(searchTextDogecoin,startTextDogecoin,endTextDogeecoin)将 tid 设置为 AppleScript 的文本项分隔符将 startTextDogecoin 设置为>";将 searchTextDogecoin 设置为 {priceValue___11gHJ", 0 &searchTextDogecoin}将 AppleScript 的文本项分隔符设置为 startTextDogecoin将 endItemsDogecoin 设置为 searchTextDogecoin 的文本项 -2将 AppleScript 的文本项分隔符设置为 endTextDogeecoin将 beginToEndDogecoin 设置为 endItemsDogecoin 的文本项 1将 AppleScript 的文本项分隔符设置为 startTextDogecoin将 endTextDogeecoin 设置为(beginningToEndDogecoin 的文本项 2 到 -1)作为记录将 AppleScript 的文本项分隔符设置为 tid结束提取文本狗狗币--打开股票计量网页的tell语句--告诉应用程序Safari"启用做shell脚本打开https://coinmarketcap.com/currencies/bitcoin/"结束告诉延迟 2--按类别和编号区分网页上数据的功能.它-- 还使用 JavaScript 将数据写入可用的格式.到 getInputByClassBitcoin(theClass, num)告诉应用程序Safari"设置输入以执行 JavaScript "document.getElementsByClassName('" & theClass & "')[";&编号 &"].innerHTML;"在文件 1结束告诉返回输入结束 getInputByClassBitcoin--手动从网页中拉取类和编号条件的函数--getInputByClassBitcoin("priceValue___11gHJ", 0)--将瞬时股价设置为变量以在Excel中输入--将 BitcoinPrice 设置为 getInputByClassBitcoin("priceValue___11gHJ", 0)在 FinalFuction(BitcoinPrice)将 FinalFuction 设置为 extractTextBitcoin(BitcoinPrice, "

", "

")返回 FinalFuction(BitcoinPrice)结束最终函数告诉应用程序Safari"启用做shell脚本打开https://coinmarketcap.com/currencies/litecoin/";结束告诉延迟 2到 getInputByClassLitecoin(theClass, num)告诉应用程序Safari"设置令牌以执行 JavaScript "document.getElementsByClassName('" & theClass & "')[";&编号 &"].innerHTML;"在文件 1结束告诉返回令牌结束 getInputByClassLitecoingetInputByClassLitecoin("priceValue___11gHJ", 0)将 LitecoinPrice 设置为 getInputByClassLitecoin("priceValue___11gHJ", 0)返回函数(莱特币价格)将 ReturnFuction 设置为 extractTextLitecoin(LitecoinPrice, "

", "

")返回返回函数(莱特币价格)结束返回函数告诉应用程序Safari"启用做shell脚本打开https://coinmarketcap.com/currencies/dogecoin/";结束告诉延迟 2到 getInputByClassDogecoin(theClass, num)告诉应用程序Safari"设置爆炸来做 JavaScript "document.getElementsByClassName('" & theClass & "')[";&编号 &"].innerHTML;"在文件 1结束告诉返回爆炸结束 getInputByClassDogecoingetInputByClassDogecoin("priceValue___11gHJ", 0)将狗狗币价格设置为 getInputByClassDogecoin("priceValue___11gHJ", 0)在 EndFuction(狗狗币价格)将 EndFuction 设置为 extractTextDogecoin(DogecoinPrice, "

", "

")返回 EndFuction(DogecoinPrice)结束功能--打开编译好的Excel工作簿,否定用户输入,找到下一个可用的----输入数据的单元格,并用年、月、日、时间和价格填充字段--告诉应用程序Microsoft Excel"打开/Users/clusterflux/Desktop/ㅇㅅㅇBITCOINㅇㅅㅇ.xlsx";将显示警报设置为 false删除活动工作表(获取结束(第 9 列的最后一个单元格)方向的第一行索引朝向顶部)将 LastRow 设置为(获取结束(第 9 列的最后一个单元格)方向朝向顶部)的第一行索引--将每个市场读数的日期和时间写入excel文件将单元格的值(I"和LastRow + 1)设置为=YEAR(TODAY())";将单元格的值(J"和LastRow + 1)设置为=MONTH(TODAY())";将单元格的值(K"和LastRow + 1)设置为=DAY(TODAY())";将单元格的值(L"和LastRow + 1)设置为((当前日期)的时间字符串)将单元格的值(M"和 LastRow + 1)设置为 BitcoinPrice将 workbookName 设置为 ("ㅇㅅㅇBITCOINㅇㅅㅇ.xlsx") 作为字符串将 destinationPath 设置为(桌面路径为文本)&工作簿名称在 destinationPath 中保存活动工作簿结束告诉告诉应用程序Microsoft Excel"打开/Users/clusterflux/Desktop/ㅇㅅㅇLITECOINㅇㅅㅇ.xlsx";将显示警报设置为 false删除活动工作表第一行索引(获取结束(第 5 列的最后一个单元格)朝向顶部的方向)将 LastRow 设置为(获取结束(第 5 列的最后一个单元格)方向朝向顶部)的第一行索引将单元格的值(C"和LastRow + 1)设置为=YEAR(TODAY())";将单元格的值(D"和LastRow + 1)设置为=MONTH(TODAY())";将单元格的值(E"和LastRow + 1)设置为=DAY(TODAY())";将单元格的值(F"和LastRow + 1)设置为((当前日期)的时间字符串)将单元格的值(G"和 LastRow + 1)设置为 LitecoinPrice将 workbookName 设置为 ("ㅇㅅㅇLITECOINㅇㅅㅇ.xlsx") 作为字符串将 destinationPath 设置为(桌面路径为文本)&工作簿名称在 destinationPath 中保存活动工作簿结束告诉空闲时返回 3嘟告诉应用程序Microsoft Excel"打开/Users/clusterflux/Desktop/ㅇㅅㅇDOGECOINㅇㅅㅇ.xlsx";将显示警报设置为 false删除活动工作表第一行索引(获取结束(第 5 列的最后一个单元格)朝向顶部的方向)将 LastRow 设置为(获取结束(第 5 列的最后一个单元格)方向朝向顶部)的第一行索引将单元格的值(C"和LastRow + 1)设置为=YEAR(TODAY())";将单元格的值(D"和LastRow + 1)设置为=MONTH(TODAY())";将单元格的值(E"和LastRow + 1)设置为=DAY(TODAY())";将单元格的值(F"和LastRow + 1)设置为((当前日期)的时间字符串)将单元格(G"和LastRow + 1)的值设置为DogecoinPrice将 workbookName 设置为 ("ㅇㅅㅇDOGECOINㅇㅅㅇ.xlsx") 作为字符串将 destinationPath 设置为(桌面路径为文本)&工作簿名称在 destinationPath 中保存活动工作簿结束告诉结束空闲

如果我的格式不符合要求,请提前抱歉.我还是个新手.

解决方案

这是一种不同的 AppleScript 方法,它允许您检索比特币价格值,而无需打开 Safari、使用 JavaScript、Automator 或使用文本项分隔符.这可能不是您正在寻找的,但至少它提供了一种使用更少代码的不同方法.希望您可以根据自己的需要调整其中的一些内容.

代码中的前 3 个属性定义了 正则表达式,它将在 do shell script 命令中使用,它将从 HTML 源代码中提取美元值.

例如,快速解释什么property eGrepBitcoinPrice : "priceValue___11gHJ\">\\$\\d{2},\\d{3}.\\d{2}" 意味着……我们将在 HTML 中搜索包含priceValue___11gHJ"后跟>"的文本后跟$",后跟任意 2 位数字,后跟,",后跟任意 3 位数字,后跟."后跟任意 2 位数字

因为我没有 Microsoft Excel,所以无法在代码中包含这些命令.但是,我确实创建了一个快速记录功能,将价格写入桌面上的纯文本文件Price Log.txt".可以轻松禁用或删除此功能.日志命令都包含在一个名为 script logCommandsscript object 中,它可以与包含 my logCommands 的代码中的任何其他行一起删除或注释掉.

这是日志文件的快照

将以下 AppleScript 代码保存在 Script Editor.app 中作为保持打开"的应用程序.由于它是一个保持打开"的应用程序,当小程序在 Script Editor.app 之外启动时,只有显式 on run 处理程序中的内容只会运行一次.其余的魔法发生在 on idle 处理程序中......并且这个处理程序中的所有内容将每 300 秒运行一次.如果您希望命令每 30 分钟重复一次,只需将 return 值设置为 1800.

property eGrepBitcoinPrice : "priceValue___11gHJ\">\\$\\d{2},\\d{3}.\\d{2}";属性 eGrepLitecoinPrice : "priceValue___11gHJ\>\\$\\d{3}.\\d{2}"属性 eGrepDogecoinPrice : "priceValue___11gHJ\>\\$\\d{1}.\\d{5}"属性 currentBitcoinPrice :缺失值属性 currentLitecoinPrice :缺失值属性 currentDogecoinPrice :缺失值属性 logToTextFile :缺失值运行时 -- 仅执行一次.. 启动此脚本小程序时启用将 logToTextFile 设置为(显示对话框 ¬启用快速日志模式?"按钮 {否",是"} ¬标题为日志模式"的默认按钮 2)如果按钮返回 logToTextFile = "Yes";然后我的 logCommands 的 beginLog()获取价格()别的获取价格()返回 {currentBitcoinPrice, currentDogecoinPrice, currentLitecoinPrice}万一结束运行空闲时获取价格()如果按钮返回 logToTextFile = "Yes";然后我的 logCommands 的 writeToLog()(* 在此空闲处理程序中,您将放置您的大部分附加代码.你所有的 Excel代码在这里*)return 300 -- 在几秒钟内,在这个空闲处理程序中运行代码的频率结束空闲---------- 将所有附加处理程序放在这条线下方 ----------在 getPrices()设置 currentBitcoinPrice 来做 shell 脚本 ¬"curl --no-keepalive 'https://coinmarketcap.com/currencies/bitcoin/markets/' "&¬"|grep -Eo "&eGrepBitcoinPrice & 的报价形式"|cut -c 21-"设置 currentLitecoinPrice 来做 shell 脚本 ¬"curl --no-keepalive 'https://coinmarketcap.com/currencies/litecoin/' "&¬"|grep -Eo "&eGrepLitecoinPrice & 的报价形式"|cut -c 21-"设置 currentDogecoinPrice 来做 shell 脚本 ¬"curl --no-keepalive 'https://coinmarketcap.com/currencies/dogecoin/' "&¬"|grep -Eo "&eGrepDogecoinPrice & 的引用形式"|cut -c 21-"结束获取价格on quit -- 仅在脚本退出时执行如果按钮返回 logToTextFile = "Yes";然后我的 logCommands 的 endLog()继续退出——允许脚本退出结束退出脚本日志命令属性 pathToPriceLog :(作为文本的桌面路径)的 POSIX 路径 &价格日志.txt"在 beginLog()将 startTime 设置为 ("Start Time..." & (current date) as text) &¬"以 5 分钟为间隔扫描价格"做shell脚本echo"&开始时间">>"&¬pathToPriceLog 的引用形式结束开始日志在 writeToLog() 上做shell脚本echo"&比特币:"&currentBitcoinPrice & 的报价形式¬"狗狗币:"&currentDogecoinPrice & 的报价形式¬"莱特币:"&currentLitecoinPrice & 的报价形式¬""&((当前日期)的时间字符串) &的引用形式¬">>"&pathToPriceLog 的引用形式结束 writeToLog在 endLog()将 endTime 设置为End Time..."的引用形式;&(当前日期)作为文本做shell脚本echo"&结束时间">>"&¬pathToPriceLog 的引用形式做shell脚本echo"&""&">>"&¬pathToPriceLog 的引用形式结束日志结束脚本

不幸的是,当从 Script Editor.app 中启动时,保持打开"的应用程序和脚本不会执行 idle handler 中的内容.因此,需要从 Finder 中启动保持打开"应用程序,就像任何其他应用程序一样,在 idle 命令发生时观察它们的结果.这是我包含日志记录到文件功能的主要原因……所以我可以实时观察 idle 命令的结果.

与很多人的想法相反,大多数保持开放"的应用程序使用很少的系统资源.


由于更改了 URL 源代码而更新了 APPLESCRIPT 代码

property eGrepBitcoinPrice : "priceValue\\ \">\\$\\d{2},\\d{3}.\\d{2}"属性 eGrepLitecoinPrice : "priceValue\\ \>\\$\\d{3}.\\d{2}"属性 eGrepDogecoinPrice : "priceValue\\ \>\\$\\d{1}.\\d{4}"属性 currentBitcoinPrice :缺失值属性 currentLitecoinPrice :缺失值属性 currentDogecoinPrice :缺失值属性 logToTextFile :缺失值运行时 -- 仅执行一次.. 启动此脚本小程序时启用将 logToTextFile 设置为(显示对话框 ¬启用快速日志模式?"按钮 {否",是"} ¬标题为日志模式"的默认按钮 2)如果按钮返回 logToTextFile = "Yes";然后我的 logCommands 的 beginLog()获取价格()别的获取价格()返回 {currentBitcoinPrice, currentDogecoinPrice, currentLitecoinPrice}万一结束运行空闲时获取价格()尝试如果按钮返回 logToTextFile = "Yes";然后我的 logCommands 的 writeToLog()错误 errMsg 编号 errNum我的 logCommands 的 writeToLog()结束尝试(* 在此空闲处理程序中,您将放置您的大部分附加代码.你所有的 Excel代码在这里*)return 300 -- 在几秒钟内,在这个空闲处理程序中运行代码的频率结束空闲---------- 将所有附加处理程序放在这条线下方 ----------在 getPrices()设置 currentBitcoinPrice 来做 shell 脚本 ¬"curl --no-keepalive 'https://coinmarketcap.com/currencies/bitcoin/markets/' "&¬"|grep -Eo "&eGrepBitcoinPrice & 的报价形式"|cut -c 14-"设置 currentLitecoinPrice 来做 shell 脚本 ¬"curl --no-keepalive 'https://coinmarketcap.com/currencies/litecoin/' "&¬"|grep -Eo "&eGrepLitecoinPrice & 的报价形式"|cut -c 14-"设置 currentDogecoinPrice 来做 shell 脚本 ¬"curl --no-keepalive 'https://coinmarketcap.com/currencies/dogecoin/' "&¬"|grep -Eo "&eGrepDogecoinPrice & 的引用形式"|cut -c 14-"结束获取价格on quit -- 仅在脚本退出时执行如果按钮返回 logToTextFile = "Yes";然后我的 logCommands 的 endLog()继续退出——允许脚本退出结束退出脚本日志命令属性 pathToPriceLog :(作为文本的桌面路径)的 POSIX 路径 &价格日志.txt"在 beginLog()将 startTime 设置为 ("Start Time..." & (current date) as text) &¬"以 5 分钟为间隔扫描价格"做shell脚本echo"&开始时间">>"&¬pathToPriceLog 的引用形式结束开始日志在 writeToLog() 上做shell脚本echo"&比特币:"&currentBitcoinPrice & 的报价形式¬"狗狗币:"&currentDogecoinPrice & 的报价形式¬"莱特币:"&currentLitecoinPrice & 的报价形式¬""&((当前日期)的时间字符串) &的引用形式¬">>"&pathToPriceLog 的引用形式结束 writeToLog在 endLog()将 endTime 设置为End Time..."的引用形式;&(当前日期)作为文本做shell脚本echo"&结束时间">>"&¬pathToPriceLog 的引用形式做shell脚本echo"&""&">>"&¬pathToPriceLog 的引用形式结束日志结束脚本

I have been exploring coding recently and I really enjoy grinding a problem down. I am getting comfortable with AppleScript now and I think it is a good option for what I want to do in the future with coding. My gut tells me that Automator would be less efficient RAM wise and I don't like how it is sectioned off; to constraining and confusing. I like the sandbox feature of a scripting language. I built a pretty good script for a web crawler that opens an online stock portfolio and prunes the market price of cryptocurrencies. I plan on utilizing technological decision making labs to create a cryptocurrency forecasting workbook for my hopes and dreams to make money some day, if ever :[ I have day dreams of making a live excel file that builds plots with hourly fluctuations in the trading.

To make it a full fledged automated system I need some sort of way to loop the script or schedule it to run on a schedule to get lots of data points for the mathematical models I hope to formulate from the data. I have tried really hard to make the idle handler work but it just doesn't operate like the tutorials describe. It seems you can't use "on idle" with certain commands and I get an error every gosh darn time I use the thing. I found a help page that showed how to incorporate a "beep" function to make sure the idle loop is running and when I compile and save as an "always running App" it doesn't play the beep so I guess that's another problem I haven't figured out. I get the beep to work sometimes but with my final draft of my program now I can't get it to work. I have tried inserting it ever so carefully within tell statements because I have found it works with them sometimes. And I guess you can't have the idle handler span the entire script; it needs to be called in one command structures tree to work. But I still haven't had the App run the script from idle with all the work I've put in looking into this solution. Anybody that has the hush hush on the idle handler secrets can do their best to try to explain the inner workings of the script to me but I find that it takes me a long time to learn coding because it is a lot of very technical reading with precious few opportunities to forge your own learning. Coding is a lot of boiler plate rehashes and I assume I will be chipping away at writing code long into my grey hair days with what I've learned so far.

But if you could use this question to collect some reading material on how to take a moderately well written script to run in 30 minute increments in the background of a laptop that can handle most computing loads fairly well it would be most appreciated. I'm not against Automator; it's just hard in it's own right with all the things you have to know to get it to work. As I said, any info about the idle handler and how to get it to work would be helpful. Also, if it is possible to write code in AppleScript to generate plots in Microsoft Excel, I like making models for shirts and googles.

I guess I will share what I've worked on for the last chunk of a weeks worth of grinding the tutorials offered currently online for free. Any critiques or suggestions on how to make the script I've got so far better is greatly appreciated and I don't mind if you snatch something you like if I did a good jerb. This is a web crawling cryptocurrency stock analyzer currently. It follows 3 currencies and writes data to an excel file with year, month, day, and seconds to collect a mass of data for a stronger mathematical model. I studied technological forecasting techniques that apply seasonality to data so the forecasts are better than just using the trend line function in excel, though with the variability with cryptocurrency I wouldn't put much salt on a long term prediction of market prices. I just want to be watching for those oh so gut wrenching stock crashes for a chance to limp in to the game with what little money I can scrounge together for sustenance.

--Boiler plate code to manipulate the HTML to let us pull the market price of the stock.--
--3 sets of modifiers for the 3 stocks--
to extractTextBitcoin(searchTextBitcoin, startTextBitcoin, endTextBitcoin)
    set tid to AppleScript's text item delimiters
    set startTextBitcoin to ">"
    set searchTextBitcoin to {"priceValue___11gHJ", 0 & searchTextBitcoin}
    set AppleScript's text item delimiters to startTextBitcoin
    set endItemsBitcoin to text item -1 of searchTextBitcoin
    set AppleScript's text item delimiters to endTextBitcoin
    set beginningToEndBitcoin to text item 1 of endItemsBitcoin
    set AppleScript's text item delimiters to startTextBitcoin
    set endTextBitcoin to (text items 2 thru -1 of beginningToEndBitcoin) as record
    set AppleScript's text item delimiters to tid
end extractTextBitcoin

to extractTextLitecoin(searchTextLitecoin, startTextLitecoin, endTextLitecoin)
    set tid to AppleScript's text item delimiters
    set startTextLitecoin to ">"
    set searchTextLitecoin to {"priceValue___11gHJ", 0 & searchTextLitecoin}
    set AppleScript's text item delimiters to startTextLitecoin
    set endItemsLitecoin to text item -1 of searchTextLitecoin
    set AppleScript's text item delimiters to endTextLitecoin
    set beginningToEndLitecoin to text item 1 of endItemsLitecoin
    set AppleScript's text item delimiters to startTextLitecoin
    set endTextLitecoin to (text items 2 thru -1 of beginningToEndLitecoin) as record
    set AppleScript's text item delimiters to tid
end extractTextLitecoin

to extractTextDogecoin(searchTextDogecoin, startTextDogecoin, endTextDogeecoin)
    set tid to AppleScript's text item delimiters
    set startTextDogecoin to ">"
    set searchTextDogecoin to {"priceValue___11gHJ", 0 & searchTextDogecoin}
    set AppleScript's text item delimiters to startTextDogecoin
    set endItemsDogecoin to text item -2 of searchTextDogecoin
    set AppleScript's text item delimiters to endTextDogeecoin
    set beginningToEndDogecoin to text item 1 of endItemsDogecoin
    set AppleScript's text item delimiters to startTextDogecoin
    set endTextDogeecoin to (text items 2 thru -1 of beginningToEndDogecoin) as record
    set AppleScript's text item delimiters to tid
end extractTextDogecoin

--A tell statement to open the webpage where the stocks are measured--
tell application "Safari"
    activate
    do shell script "open https://coinmarketcap.com/currencies/bitcoin/"
end tell

delay 2

--A function that differentiates the data on the web page by class and number. It
--also uses JavaScript to write the data to a useable format.
to getInputByClassBitcoin(theClass, num)
    tell application "Safari"
        set input to do JavaScript "
        document.getElementsByClassName('" & theClass & "')[" & num & "].innerHTML;" in document 1
    end tell
    return input
end getInputByClassBitcoin

--The function with the class and number criteria manually pulled from the web page--
getInputByClassBitcoin("priceValue___11gHJ", 0)

--Setting the instataneous stock price to a variable to input in Excel--
set BitcoinPrice to getInputByClassBitcoin("priceValue___11gHJ", 0)
on FinalFuction(BitcoinPrice)
    set FinalFuction to extractTextBitcoin(BitcoinPrice, "<div class=>", "</div>")
    return FinalFuction(BitcoinPrice)
end FinalFuction

tell application "Safari"
    activate
    do shell script "open https://coinmarketcap.com/currencies/litecoin/"
end tell

delay 2

to getInputByClassLitecoin(theClass, num)
    tell application "Safari"
        set token to do JavaScript "
        document.getElementsByClassName('" & theClass & "')[" & num & "].innerHTML;" in document 1
    end tell
    return token
end getInputByClassLitecoin

getInputByClassLitecoin("priceValue___11gHJ", 0)

set LitecoinPrice to getInputByClassLitecoin("priceValue___11gHJ", 0)
on ReturnFuction(LitecoinPrice)
    set ReturnFuction to extractTextLitecoin(LitecoinPrice, "<div class=>", "</div>")
    return ReturnFuction(LitecoinPrice)
end ReturnFuction

tell application "Safari"
    activate
    do shell script "open https://coinmarketcap.com/currencies/dogecoin/"
end tell

delay 2

to getInputByClassDogecoin(theClass, num)
    tell application "Safari"
        set blast to do JavaScript "
        document.getElementsByClassName('" & theClass & "')[" & num & "].innerHTML;" in document 1
    end tell
    return blast
end getInputByClassDogecoin

getInputByClassDogecoin("priceValue___11gHJ", 0)

set DogecoinPrice to getInputByClassDogecoin("priceValue___11gHJ", 0)
on EndFuction(DogecoinPrice)
    set EndFuction to extractTextDogecoin(DogecoinPrice, "<div class=>", "</div>")
    return EndFuction(DogecoinPrice)
end EndFuction

--Opens the compiled Excel workbook, negates user input, finds the next available--
--cell to input data, and fills the fields with Year, Month, Day, Time, and Price--
tell application "Microsoft Excel"
    open "/Users/clusterflux/Desktop/ㅇㅅㅇBITCOINㅇㅅㅇ.xlsx"
    set display alerts to false
    delete active sheet
    first row index of (get end (last cell of column 9) direction toward the top)
    set LastRow to first row index of (get end (last cell of column 9) direction toward the top)
    --write date and time for each market reading to excel file
    set value of cell ("I" & LastRow + 1) to "=YEAR(TODAY())"
    set value of cell ("J" & LastRow + 1) to "=MONTH(TODAY())"
    set value of cell ("K" & LastRow + 1) to "=DAY(TODAY())"
    set value of cell ("L" & LastRow + 1) to (time string of (current date))
    set value of cell ("M" & LastRow + 1) to BitcoinPrice
    set workbookName to ("ㅇㅅㅇBITCOINㅇㅅㅇ.xlsx") as string
    set destinationPath to (path to desktop as text) & workbookName
    save active workbook in destinationPath
end tell

tell application "Microsoft Excel"
    open "/Users/clusterflux/Desktop/ㅇㅅㅇLITECOINㅇㅅㅇ.xlsx"
    set display alerts to false
    delete active sheet
    first row index of (get end (last cell of column 5) direction toward the top)
    set LastRow to first row index of (get end (last cell of column 5) direction toward the top)
    set value of cell ("C" & LastRow + 1) to "=YEAR(TODAY())"
    set value of cell ("D" & LastRow + 1) to "=MONTH(TODAY())"
    set value of cell ("E" & LastRow + 1) to "=DAY(TODAY())"
    set value of cell ("F" & LastRow + 1) to (time string of (current date))
    set value of cell ("G" & LastRow + 1) to LitecoinPrice
    set workbookName to ("ㅇㅅㅇLITECOINㅇㅅㅇ.xlsx") as string
    set destinationPath to (path to desktop as text) & workbookName
    save active workbook in destinationPath
end tell
on idle
    return 3
    beep
    tell application "Microsoft Excel"
        open "/Users/clusterflux/Desktop/ㅇㅅㅇDOGECOINㅇㅅㅇ.xlsx"
        set display alerts to false
        delete active sheet
        first row index of (get end (last cell of column 5) direction toward the top)
        set LastRow to first row index of (get end (last cell of column 5) direction toward the top)
        set value of cell ("C" & LastRow + 1) to "=YEAR(TODAY())"
        set value of cell ("D" & LastRow + 1) to "=MONTH(TODAY())"
        set value of cell ("E" & LastRow + 1) to "=DAY(TODAY())"
        set value of cell ("F" & LastRow + 1) to (time string of (current date))
        set value of cell ("G" & LastRow + 1) to DogecoinPrice
        set workbookName to ("ㅇㅅㅇDOGECOINㅇㅅㅇ.xlsx") as string
set destinationPath to (path to desktop as text) & workbookName
        save active workbook in destinationPath
    end tell
end idle

Sorry in advance if my formatting isn't up to snuff. I'm still a newbie.

解决方案

Here is a different AppleScript approach which allows you to retrieve your Bitcoin Price values without the need for opening Safari, using JavaScript, Automator, or using text item delimiters. This may not be exactly what you’re looking for but at least it offers a different approach using much less code. Hopefully you can adapt some of it to your needs.

The first 3 properties in the code define the regular expressions which will be used in the do shell script commands, which will extract the dollar values from the HTML source code.

For example, to quickly explain what property eGrepBitcoinPrice : "priceValue___11gHJ\">\\$\\d{2},\\d{3}.\\d{2}" means… we will be searching for text inside the HTML which contains "priceValue___11gHJ" followed by a ">" followed by "$" followed by any 2 digits followed by a "," followed by any 3 digits followed by a "." and followed by any 2 digits

Because I do not have Microsoft Excel, I could not include those commands in the code. However, I did create a quick logging function which writes the prices to a plain text file on your Desktop "Price Log.txt". This functionality can easily be disabled or removed. The log commands are all wrapped up within a script object called script logCommands which can be removed or commented out along with any other lines in the code which contain my logCommands's.

Here is a snapshot of the log file

Save this following AppleScript code in Script Editor.app as a "stay open" application. Being that it is a "stay open" application, when the applet is launched outside of Script Editor.app, only what is within the explicit on run handler will run only one time. The rest of the magic happens within the on idle handler… and everything within this handler will run every 300 seconds. If you want the commands to repeat every 30 minutes, just set the return value to 1800.

property eGrepBitcoinPrice : "priceValue___11gHJ\">\\$\\d{2},\\d{3}.\\d{2}"
property eGrepLitecoinPrice : "priceValue___11gHJ\">\\$\\d{3}.\\d{2}"
property eGrepDogecoinPrice : "priceValue___11gHJ\">\\$\\d{1}.\\d{5}"
property currentBitcoinPrice : missing value
property currentLitecoinPrice : missing value
property currentDogecoinPrice : missing value
property logToTextFile : missing value

on run --   Executed Only Once.. When This Script Applet Is Launched
    activate
    set logToTextFile to (display dialog ¬
        "Enable Quick Log Mode?" buttons {"No", "Yes"} ¬
        default button 2 with title "Log Mode")
    if button returned of logToTextFile = "Yes" then
        my logCommands's beginLog()
        getPrices()
    else
        getPrices()
        return {currentBitcoinPrice, currentDogecoinPrice, currentLitecoinPrice}
    end if
end run

on idle
    getPrices()
    if button returned of logToTextFile = "Yes" then my logCommands's writeToLog()
    
    (* within this idle handler is where you will place
    The bulk of your additional code. All of your Excel
    Code Goes Here*)
    
    return 300 -- In Seconds, How Often To Run Code In This Idle Handler
end idle

---------- PLACE ALL ADDITIONAL HANDLERS BENEATH THIS LINE ----------

on getPrices()
    set currentBitcoinPrice to do shell script ¬
        "curl --no-keepalive 'https://coinmarketcap.com/currencies/bitcoin/markets/' " & ¬
        "| grep -Eo " & quoted form of eGrepBitcoinPrice & " | cut -c 21-"
    set currentLitecoinPrice to do shell script ¬
        "curl --no-keepalive 'https://coinmarketcap.com/currencies/litecoin/' " & ¬
        "| grep -Eo " & quoted form of eGrepLitecoinPrice & " | cut -c 21-"
    set currentDogecoinPrice to do shell script ¬
        "curl --no-keepalive 'https://coinmarketcap.com/currencies/dogecoin/' " & ¬
        "| grep -Eo " & quoted form of eGrepDogecoinPrice & " | cut -c 21-"
end getPrices

on quit --  Executed Only When The Script Quits
    if button returned of logToTextFile = "Yes" then my logCommands's endLog()
    continue quit -- Allows The Script To Quit
end quit

script logCommands
    property pathToPriceLog : POSIX path of (path to desktop as text) & "Price Log.txt"
    on beginLog()
        set startTime to ("Start Time... " & (current date) as text) & ¬
            " Price Scanning At 5 Minute Intervals"
        do shell script "echo " & startTime & " >> " & ¬
            quoted form of pathToPriceLog
    end beginLog
    on writeToLog()
        do shell script "echo " & "Bitcoin:" & quoted form of currentBitcoinPrice & ¬
            "   Dogecoin:" & quoted form of currentDogecoinPrice & ¬
            "  Litecoin:" & quoted form of currentLitecoinPrice & ¬
            "     " & quoted form of (time string of (current date)) & ¬
            " >> " & quoted form of pathToPriceLog
    end writeToLog
    on endLog()
        set endTime to quoted form of "End Time... " & (current date) as text
        do shell script "echo " & endTime & " >> " & ¬
            quoted form of pathToPriceLog
        do shell script "echo " & " " & " >> " & ¬
            quoted form of pathToPriceLog
    end endLog
end script

Unfortunately "stay open" applications and scripts when launched from within Script Editor.app, will not execute what is within the idle handler. So the "stay open" application needs to be launched from within Finder, like any other applications, to observe the results of the idle commands as they are happening. This was the main reason I included a logging to file function… so I could observe the results of the idle commands in real time.

Contrary to what a lot of people think, most "stay open" applications use very little system resources.


UPDATED APPLESCRIPT CODE DUE TO CHANGED URL SOURCE CODE

property eGrepBitcoinPrice : "priceValue\\ \">\\$\\d{2},\\d{3}.\\d{2}"
property eGrepLitecoinPrice : "priceValue\\ \">\\$\\d{3}.\\d{2}"
property eGrepDogecoinPrice : "priceValue\\ \">\\$\\d{1}.\\d{4}"
property currentBitcoinPrice : missing value
property currentLitecoinPrice : missing value
property currentDogecoinPrice : missing value
property logToTextFile : missing value

on run --   Executed Only Once.. When This Script Applet Is Launched
    activate
    set logToTextFile to (display dialog ¬
        "Enable Quick Log Mode?" buttons {"No", "Yes"} ¬
        default button 2 with title "Log Mode")
    if button returned of logToTextFile = "Yes" then
        my logCommands's beginLog()
        getPrices()
    else
        getPrices()
        return {currentBitcoinPrice, currentDogecoinPrice, currentLitecoinPrice}
    end if
end run

on idle
    getPrices()
    try
        if button returned of logToTextFile = "Yes" then my logCommands's writeToLog()
    on error errMsg number errNum
        my logCommands's writeToLog()
    end try
    
    (* within this idle handler is where you will place
    The bulk of your additional code. All of your Excel
    Code Goes Here*)
    
    return 300 -- In Seconds, How Often To Run Code In This Idle Handler
end idle

---------- PLACE ALL ADDITIONAL HANDLERS BENEATH THIS LINE ----------

on getPrices()
    set currentBitcoinPrice to do shell script ¬
        "curl --no-keepalive 'https://coinmarketcap.com/currencies/bitcoin/markets/' " & ¬
        "| grep -Eo " & quoted form of eGrepBitcoinPrice & " | cut -c 14-"
    set currentLitecoinPrice to do shell script ¬
        "curl --no-keepalive 'https://coinmarketcap.com/currencies/litecoin/' " & ¬
        "| grep -Eo " & quoted form of eGrepLitecoinPrice & " | cut -c 14-"
    set currentDogecoinPrice to do shell script ¬
        "curl --no-keepalive 'https://coinmarketcap.com/currencies/dogecoin/' " & ¬
        "| grep -Eo " & quoted form of eGrepDogecoinPrice & " | cut -c 14-"
end getPrices

on quit --  Executed Only When The Script Quits
    if button returned of logToTextFile = "Yes" then my logCommands's endLog()
    continue quit -- Allows The Script To Quit
end quit

script logCommands
    property pathToPriceLog : POSIX path of (path to desktop as text) & "Price Log.txt"
    on beginLog()
        set startTime to ("Start Time... " & (current date) as text) & ¬
            " Price Scanning At 5 Minute Intervals"
        do shell script "echo " & startTime & " >> " & ¬
            quoted form of pathToPriceLog
    end beginLog
    on writeToLog()
        do shell script "echo " & "Bitcoin:" & quoted form of currentBitcoinPrice & ¬
            "   Dogecoin:" & quoted form of currentDogecoinPrice & ¬
            "  Litecoin:" & quoted form of currentLitecoinPrice & ¬
            "     " & quoted form of (time string of (current date)) & ¬
            " >> " & quoted form of pathToPriceLog
    end writeToLog
    on endLog()
        set endTime to quoted form of "End Time... " & (current date) as text
        do shell script "echo " & endTime & " >> " & ¬
            quoted form of pathToPriceLog
        do shell script "echo " & " " & " >> " & ¬
            quoted form of pathToPriceLog
    end endLog
end script

这篇关于初学者 AppleScript Writer 遇到空闲处理程序问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆