AppleScript 在解析大型 json 结构时无法完成

问题描述 投票:0回答:2

我有一台装有 Monterey 12.6 的 iMac 2017。

我被迫在 python 中调用我的 API 以获得正确的 JSON 结构的结果。

仅供参考,这是我在 python 中调用的 URL(coingecko 将结果限制为前 100 个结果):

https://api.coingecko.com/api/v3/coins/markets?ids=acala,alpaca-finance,altair,astar,avalanche-2,baanx,bbeefy-finance,bifrost-native-coin,binancecoin,binance-eth,binance-usd,bitcoin,cardano,chainlink,chainx,chronicle,coin-capsule,colony,cosmos,crabada,crypto-com-chain,cumrocket,curve-dao-token,dappradar,dogecoin,elrond-erd-2,ergo,ethereum,evmos,exeedme,fantom,ftx-token,fuse-network-token,genshiro,green-satoshi-token,havven,hooked-protocol,integritee,kadena,karura,kintsugi,kucoin-shares,kusama,kuswap,matic-network,metagame-arena,metagods,metavault,mina-protocol,moonbeam,moonpot,moonriver,nafty,near,osmosis,pancakeswap-token,paraswap,platypus-finance,pluton,polkadot,safemoon,shiba-inu,kryll,kucoin-shares,kusama,kuswap,lido-dao,matic-network,maze-token,memepad,metagame-arena,metagods,metis-token,mina-protocol,moonbeam,moonpot,moonriver,movn,nafter,nafty,near,nexo,nftlaunch,orion-protocol,osmosis,paid-network,pancakeswap-token,paraswap,platypus-finance,polkadot,polkamon,polkamarkets,polkastarter,polycat-finance,polychain-monsters,polygonfarm-finance,presearch,safemoon,safepal,shiba-inu,shiden,solana,staked-ether,staked-olympus,stasis-eurs,stepn,sushi,swissborg,switch,tether,terrausd,the-graph,the-sandbox,unifarm,uniswap,usd-coin,valkyrie-protocol,wizarre-scroll,zelcash&vs_currency=EUR"

Python 中的结果与此类似,但对于许多其他加密货币:

[{'id': 'bitcoin', 'symbol': 'btc', 'name': 'Bitcoin', 'image': 'https://assets.coingecko.com/coins/images/1/large/bitcoin.png?1547033579', 'current_price': 15765.21, 'market_cap': 303279048538, 'market_cap_rank': 1, 'fully_diluted_valuation': 330971307514, 'total_volume': 9519061248, 'high_24h': 15812.98, 'low_24h': 15758.06, 'price_change_24h': -18.11016048005331, 'price_change_percentage_24h': -0.11474, 'market_cap_change_24h': -207406972.0255127, 'market_cap_change_percentage_24h': -0.06834, 'circulating_supply': 19242937.0, 'total_supply': 21000000.0, 'max_supply': 21000000.0, 'ath': 59717, 'ath_change_percentage': -73.60052, 'ath_date': '2021-11-10T14:24:11.849Z', 'atl': 51.3, 'atl_change_percentage': 30631.82104, 'atl_date': '2013-07-05T00:00:00.000Z', 'roi': None, 'last_updated': '2022-12-25T14:21:15.974Z'}, {'id': 'ethereum', 'symbol': 'eth', 'name': 'Ethereum', 'image': 'https://assets.coingecko.com/coins/images/279/large/ethereum.png?1595348880', 'current_price': 1142.38, 'market_cap': 137652680087, 'market_cap_rank': 2, 'fully_diluted_valuation': 137652680087, 'total_volume': 2165257956, 'high_24h': 1149.42, 'low_24h': 1141.8, 'price_change_24h': -1.0190823115187868, 'price_change_percentage_24h': -0.08913, 'market_cap_change_24h': -73228021.97866821, 'market_cap_change_percentage_24h': -0.05317, 'circulating_supply': 120523982.078808, 'total_supply': 120523982.078808, 'max_supply': None, 'ath': 4228.93, 'ath_change_percentage': -72.99273, 'ath_date': '2021-12-01T08:38:24.623Z', 'atl': 0.381455, 'atl_change_percentage': 299310.75605, 'atl_date': '2015-10-20T00:00:00.000Z', 'roi': {'times': 95.89474372830291, 'currency': 'btc', 'percentage': 9589.474372830291}, 'last_updated': '2022-12-25T14:20:55.699Z'}]

我的 AppleScript 的内容:

set desktop_folder to "$HOME/PycharmProjects/crypto/"
set valReturned to do shell script "python3 " & desktop_folder & "crypto.py"

set coins to (every item in valReturned) as list
repeat with n from 1 to count of coins
    set coin to item n of coins
end repeat

AppleScript 进程使用了我 99% 的处理器。

如果我评论循环部分,我有一个巨大的 JSON(这只是 100 种不同加密货币的结果)。我无法发布它,因为当我复制粘贴其内容时,它超过了 81,000 个字符。

为什么 AppleScript 会崩溃?

我已经在 Stackoverflow here 上发布了文章,但我没有以同样的方式这样做。 我认为我可以减少请求中的加密货币数量,但以这种方式崩溃仍然很奇怪。例如,我对 Excel 和 powerquery 没有任何问题。

我觉得生成 Numbers 文件的最佳方法是生成 CSV,然后使用 AppleScript 将该 CSV 导入到 Numbers 中,然后应用格式设置。有什么建议吗?

python json applescript macos-monterey
2个回答
0
投票

只能推测,因为我没有/使用任何苹果设备:

  • JSON 中没有换行符。如果使用(内部)依赖于字符串的工具/语言加载/处理它,则可能会超出字符串的最大字符限制
  • 在这两种情况下,您的
    valReturned
    都是 AppleScript 中的变量。它可能有一些大小限制,并且您可以通过来自
    echo
    pyhton3
    输出的文本字符来填充/设置它。这可能会导致延迟和大小限制(崩溃?)。尤其是使用
    echo
    ,在终端上打印文本通常受到终端的输出/绘图/渲染速度的限制,而不是计算机处理字符的速度。
  • 不确定 AppleScript 如何处理 JSON - 它是否解析 JSON 并将其全部保留在内存中?另外,它是否尝试聪明地将 JSON 反序列化/解组为自己的数据类型,创建许多对象等以供以后的编程访问?然后您似乎还有它的两个副本,一个位于
    coins
    中的列表结构中,然后是
    valReturned
    (我假设是一个字符串)。
  • 可能还有更多类似的原因......

如果您已经能够调用

echo
python3
,也许您不需要使用 AppleScript 来迭代 JSON 条目?由于您似乎能够直接将来自网络的 JSON 写入文件,也许您不需要让 AppleScript 加载/保留 JSON 数据?想知道尝试避免 AppleScript 暴露于 JSON 或外部程序的结果/输出是否会减轻性能和崩溃问题。


0
投票

AppleScript 将毫无问题地执行 shell 脚本,但请注意,结果将是一个 string。您的示例脚本只是遍历该字符串的 (81,000+) 个字符,这需要一点时间。许多语言(例如 Python)都提供对 JSON 字符串的直接支持 - 对于 AppleScript,可以使用 Cocoa(通过 AppleScriptObjC)。

可以解析 shell 脚本中的 JSON 字符串以获取记录列表(结果也可以保留为 Cocoa 对象以供这些方法使用)。然后可以使用重复语句和根据需要使用的各种记录键值逐步执行各个列表项,例如:

use framework "Foundation"
use scripting additions

set theURL to "https://api.coingecko.com/api/v3/coins/markets?ids=acala,alpaca-finance,altair,astar,avalanche-2,baanx,bbeefy-finance,bifrost-native-coin,binancecoin,binance-eth,binance-usd,bitcoin,cardano,chainlink,chainx,chronicle,coin-capsule,colony,cosmos,crabada,crypto-com-chain,cumrocket,curve-dao-token,dappradar,dogecoin,elrond-erd-2,ergo,ethereum,evmos,exeedme,fantom,ftx-token,fuse-network-token,genshiro,green-satoshi-token,havven,hooked-protocol,integritee,kadena,karura,kintsugi,kucoin-shares,kusama,kuswap,matic-network,metagame-arena,metagods,metavault,mina-protocol,moonbeam,moonpot,moonriver,nafty,near,osmosis,pancakeswap-token,paraswap,platypus-finance,pluton,polkadot,safemoon,shiba-inu,kryll,kucoin-shares,kusama,kuswap,lido-dao,matic-network,maze-token,memepad,metagame-arena,metagods,metis-token,mina-protocol,moonbeam,moonpot,moonriver,movn,nafter,nafty,near,nexo,nftlaunch,orion-protocol,osmosis,paid-network,pancakeswap-token,paraswap,platypus-finance,polkadot,polkamon,polkamarkets,polkastarter,polycat-finance,polychain-monsters,polygonfarm-finance,presearch,safemoon,safepal,shiba-inu,shiden,solana,staked-ether,staked-olympus,stasis-eurs,stepn,sushi,swissborg,switch,tether,terrausd,the-graph,the-sandbox,unifarm,uniswap,usd-coin,valkyrie-protocol,wizarre-scroll,zelcash&vs_currency=EUR"

set valReturned to (do shell script "/usr/bin/curl " & quoted form of theURL) -- string
set theResult to parseJSON from valReturned -- list of records

set output to "Current Prices:" & return -- header for the example
repeat with anItem in theResult -- the individual list items
   -- do whatever with the record key values
   set theName to |name| of anItem -- "name" is a keyword
   set theValue to current_price of anItem
   set output to output & theName & ": " & theValue & return
end repeat
return output

# Parse a JSON string into a data structure.
to parseJSON from sourceString given coercion:coerce : true
   if class of sourceString is not in {string} then error "parseJSON error: source is not a string"
   set theString to current application's NSString's stringWithString:sourceString
   set theData to theString's dataUsingEncoding:(current application's NSUTF8StringEncoding)
   set {theObject, theError} to current application's NSJSONSerialization's JSONObjectWithData:theData options:0 |error|:(reference)
   if theObject is missing value then error "parseJSON error: " & (theError's userInfo's objectForKey:"NSDebugDescription")
   if coerce then if (theObject's isKindOfClass:(current application's NSArray)) as boolean then
      return theObject as list
   else
      return theObject as record
   end if
   return theObject -- leave as NSArray or NSDictionary
end parseJSON
© www.soinside.com 2019 - 2024. All rights reserved.