1

我找到了一个用于下载加密货币信息的脚本,以便我可以使用 AppleScript 下载到 Numbers 电子表格中。这是脚本:

set mySheetName to "Coin Prices"
set myTableName to "Coin Prices"
set tgtCell to "A2"

set theHtml to do shell script "curl -s " & quoted form of "https://www.worldcoinindex.com"
set text item delimiters to {"<tbody>", "</tbody>"}
set tableContents to theHtml's text item 2 # item 2 is the body of the price table
set text item delimiters to {"<h2>"} # site uses new h2 for each currency
set tableChunks to tableContents's text items 2 thru -1
set pasteStr to ""
repeat with aChunk in tableChunks
    set text item delimiters to "><span>$ </span><span class=\"span\">"
    tell aChunk's text item 1 to set {theSymbol, thePrice} to {first word, last word}
    set pasteStr to pasteStr & theSymbol & tab & thePrice & return
end repeat
set the clipboard to pasteStr


tell application "Numbers"
    tell front document
        tell sheet mySheetName to tell table myTableName
            
            activate
            set selection range to range tgtCell
            delay 0.3
            tell application "System Events" to keystroke "v" using {option down, shift down, command down}
        end tell
    end tell
end tell

在我设置这条线之前它工作得很好:

set theHtml to do shell script "curl -s " & quoted form of "https://www.worldcoinindex.com/watchlist"

我检查了网页代码,它完全一样,但我得到一个与第 2 项有关的大而长的错误框。我不会复制和粘贴,因为错误框包含网页的整个源代码。错误看起来像这样:

无法获取文本项目 2

从那里它是源代码。

为什么这个脚本在 URL 的基础上工作而不是 URL 的子目录?

谢谢你们的帮助。

4

2 回答 2

1

由于我没有帐户可以在登录时访问https://www.worldcoinindex.com/watchlist和查看源代码,因此我相信它具有<tbody>and</tbody> 标签,并为您提供使用curl.

假设您正在使用Safari并在目标URL登录并且页面已完全加载,您可以使用以下示例 AppleScript 代码来获取您寻找的数据。

将以下代码添加到现有AppleScript 脚本的顶部,同时注释掉代码set theHtml to do shell script ...行。

tell application "Safari" to ¬
    set theHtml to do JavaScript ¬
        "document.getElementById('myTable').innerHTML;" in document 1

请注意,myTableJavaScript命令 来自主域上的,可能需要针对Watchlist进行调整。

查看页面源代码,例如:

<table id="myTable" class= ... >
<thead>

您还可以使用例如:

"document.getElementsByClassName('...')[0].innerHTML;"in document 1

替换...源代码中所示的class=



更新:

这是一个AppleScript示例 代码版本,它将打开一个新的Safari文档到目标URL,然后在后台动态创建一个Numbers文档,完成后将其置于最前面。没有使用或解析HTML的方式,它真的不应该放在首位。没有剪贴板或粘贴到Numbers中。 curl

请注意,一旦确定Safari 窗口就可以保持背景,一旦窗口id首次出现只需要一点时间,您就可以在脚本运行时将焦点设置在其他地方。新的Safari窗口在创建时实际上已经在后台,因为Safari没有被告知. activate

我为该站点创建了一个登录名,并将前三个硬币添加到我的监视列表中,这个屏幕截图是动态创建的Numbers 文档。如果这是您在示例AppleScript代码中设置的内容,它也会对主URL执行相同的操作。theURL

请注意,按照当前编码,如果未登录,它将通知您并中止脚本的运行。我希望稍后更新代码以处理未登录和动态登录(如果未登录),但这是AppleScript示例 代码的下一次迭代。

在此处输入图像描述

示例 AppleScript 代码

property theURL : "https://www.worldcoinindex.com/watchlist"
-- property theURL : "https://www.worldcoinindex.com"

property myNumbersSheetName : "Coin Prices"
property myNumbersTableName : "Coin Prices"


--  # Do not modify code below unless necessary.

property winID : missing value
property itemCount : missing value
property loginStatus : missing value
property thisNumbersDocument : missing value
property theNumbersDocumentName : missing value
property theSafariDocumentName : missing value

--  # Create a new Safari document to the target URL.
--  # Get the id of the newly created window.
--  # Wait for the page to finish loading.
--  # Get the name of the newly created document.
--  # Get Login status and if not already logged in,
--  # notify user and abort the running of the script.
--  # Get the count of ticker symbols for Numbers.

tell application "Safari"
    make new document with properties {URL:theURL}
    set winID to id of window 1
    my waitForSafariPageToFinishLoading()
    set theSafariDocumentName to name of window id winID
    tell document theSafariDocumentName
        set loginStatus to ¬
            do JavaScript ¬
                "document.getElementsByClassName('logout-nav-container')[0].innerHTML;"
        if loginStatus contains "Login" then
            display dialog ¬
                "You are not logged in!   Please login, " & ¬
                "then run script again..." buttons {"OK"} ¬
                default button 1 with title ¬
                "Login Required To Run This Script"
            return
        else
            set itemCount to my getTickerSymbolCount()
        end if
    end tell
end tell


--  # Create a new document in Numbers in the background.
--  # Create two columns and one row more than the number of
--  # ticker symbols on the page. Set the column header names.

tell application "Numbers"
    set columnCount to 2
    set rowCount to itemCount + 1
    set thisNumbersDocument to make new document
    set theNumbersDocumentName to the name of thisNumbersDocument
    tell thisNumbersDocument
        delete every table of every sheet
        tell active sheet to set its name to myNumbersSheetName
        tell sheet myNumbersSheetName
            set thisTable to ¬
                make new table with properties ¬
                    {name:myNumbersTableName ¬
                        , column count:columnCount ¬
                        , row count:rowCount}
            tell thisTable
                set value of cell "A1" to "Ticker Symbol"
                set value of cell "B1" to "Last Price"
            end tell
        end tell
    end tell
end tell


--  # Get the 'Ticker Symbol' and 'Last Price' for 
--  # the number of symbols on the page, setting their 
--  # values to the target cells in the Numbers document.

tell application "Safari"
    tell document theSafariDocumentName
        set n to 2
        repeat with i from 0 to itemCount - 1
            set |Ticker Symbol| to ¬
                first paragraph of ¬
                (do JavaScript ¬
                    "document.getElementsByClassName('ticker')[" & i & "].innerText;")
            my addToNumbersTable("A", n, |Ticker Symbol|)
            set |Last Price| to ¬
                (do JavaScript ¬
                    "document.getElementsByClassName('number pricekoers lastprice')[" & i & "].innerText;")
            my addToNumbersTable("B", n, |Last Price|)
            set n to n + 1
        end repeat
    end tell
end tell


-- # Set focus to cell A1 and bring 
-- # the Numbers document frontmost.

tell application "Numbers"
    --  # Set focus to cell A1.
    tell table myNumbersTableName of ¬
        sheet myNumbersSheetName of ¬
        document theNumbersDocumentName to ¬
        set selection range to range "A1"
    activate
end tell



--  ##  Handlers  ##

to getTickerSymbolCount()
    tell application "Safari" to ¬
        tell document ¬
            theSafariDocumentName to ¬
            return ¬
                (do JavaScript ¬
                    "document.getElementsByClassName('ticker').length;") ¬
                    as integer
end getTickerSymbolCount

to addToNumbersTable(c, n, v)
    --  # Sets the value of the target cell.    
    tell application "Numbers" to ¬
        tell table myNumbersTableName of ¬
            sheet myNumbersSheetName of ¬
            document theNumbersDocumentName to ¬
            set value of cell (c & n) to v
end addToNumbersTable

on waitForSafariPageToFinishLoading()
    --  # Wait for page to finish loading in Safari.
    --  # This works in **macOS Catalina** (10.15.7) and 
    --  # macOS Big Sur (11.4) and may need adjusting for
    --  # updated versions of Safari in these version of 
    --  # macOS, or other versions of macOS past or future.
    tell application "System Events" to repeat until ¬
        exists (buttons of groups of toolbar 1 of window 1 of ¬
            process "Safari" whose name = "Reload this page")
        delay 0.5
    end repeat
end waitForSafariPageToFinishLoading


注意:示例 AppleScript 代码就是这样,并且没有任何包含的错误处理,不包含任何可能适当的额外错误处理。用户有责任根据需要或需要添加任何错误处理。查看AppleScript 语言指南中的try 语句错误 语句。另请参阅处理错误。此外,在适当的情况下,可能需要在事件之间使用延迟命令,例如,使用延迟 delay 0.5适当设置。

于 2021-06-14T07:45:00.157 回答
0

简短的回答是主页面包含一个显式的 html 表格,而监视列表页面似乎是由 javascript 生成的一系列结构化 div 元素,并且看起来像一个表格。监视列表页面上没有“tbody”元素,因为那里没有表格。text items 命令将第一页分成三部分(第二部分是你想要的);它根本不会拆分监视列表页面,它会生成一个包含所有 html 的单个项目的数组。当您向一个包含 1 个元素的数组询问其第二项时,您会得到错误。

您将不得不检查第二页的 html 并弄清楚如何拆分文本以提取您想要的信息。

于 2021-06-13T05:22:57.997 回答