📌  相关文章
📜  将加密货币价格数据导入谷歌表格 - Go 编程语言 - Go 编程语言(1)

📅  最后修改于: 2023-12-03 15:39:15.522000             🧑  作者: Mango

使用 Go 编程语言将加密货币价格数据导入谷歌表格

介绍

在本文中,我们将讨论使用 Go 编程语言将加密货币价格数据导入到谷歌表格的过程。这个过程相对简单,但需要一些基础知识和使用 API 的经验。

前置条件

在开始编写代码之前,您需要完成以下步骤:

  1. 拥有一个谷歌账户
  2. 创建一个谷歌表格
  3. 在谷歌开发者控制台中创建一个新的项目,并启用谷歌 Sheets API。
  4. 在谷歌开发者控制台中为项目创建 OAuth2 认证信息,以便使用 Sheets API。

在完成这些步骤后,您应该已经拥有了在谷歌表格中创建和编辑数据所需的全部凭据和信息。

导入加密货币价格数据

我们将使用 CoinMarketCap API 来获取加密货币价格数据。在您开始之前,请确保您已经完成了以下步骤:

  1. 注册一个 API 池密钥
  2. 了解 API 的基本用法

我们将使用 Go 语言编写一个简单的程序来实现这个目的。这个程序将获取加密货币价格数据并将其导入到谷歌表格中。

导入依赖

首先,在您的 Go 项目中导入所需的依赖项:

package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
    "encoding/csv"
    "bytes"
    "os"

    "golang.org/x/oauth2"
    "golang.org/x/oauth2/google"
    "google.golang.org/api/sheets/v4"
)

在这里,我们将使用多个依赖项来实现我们的目标。

谷歌表格认证

在导入所需的依赖项之后,我们需要对谷歌表格进行身份验证。

func getGoogleSheetClient() (*sheets.Service, error) {
    b, err := ioutil.ReadFile("client_secret.json")
    if err != nil {
        return nil, fmt.Errorf("Unable to read client secret file: %v", err)
    }

    // If modifying these scopes, delete your previously saved client_secret.json.
    config, err := google.ConfigFromJSON(b, sheets.SpreadsheetsScope)
    if err != nil {
        return nil, fmt.Errorf("Unable to parse client secret file to config: %v", err)
    }
    client := getClient(config)

    srv, err := sheets.New(client)
    if err != nil {
        return nil, fmt.Errorf("Unable to retrieve Sheets client: %v", err)
    }
    return srv, nil
}

func getClient(config *oauth2.Config) *http.Client {
    tokFile := "token.json"
    tok, err := tokenFromFile(tokFile)
    if err != nil {
        tok = getTokenFromWeb(config)
        saveToken(tokFile, tok)
    }
    return config.Client(context.Background(), tok)
}

func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
    authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
    fmt.Printf("Go to the following link in your browser then type the "+
        "authorization code: \n%v\n", authURL)

    var authCode string
    if _, err := fmt.Scan(&authCode); err != nil {
        log.Fatalf("Unable to read authorization code: %v", err)
    }

    tok, err := config.Exchange(context.TODO(), authCode)
    if err != nil {
        log.Fatalf("Unable to retrieve token from web: %v", err)
    }
    return tok
}

func tokenFromFile(file string) (*oauth2.Token, error) {
    f, err := os.Open(file)
    if err != nil {
        return nil, err
    }
    defer f.Close()
    tok := &oauth2.Token{}
    err = json.NewDecoder(f).Decode(tok)
    return tok, err
}

func saveToken(file string, token *oauth2.Token) {
    fmt.Printf("Saving credential file to: %s\n", file)
    f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
    if err != nil {
        log.Fatalf("Unable to cache oauth token: %v", err)
    }
    defer f.Close()
    json.NewEncoder(f).Encode(token)
}

在这里,我们使用 OAuth2 认证登录谷歌表格。在客户端的 client_secret.json 文件中,我们需要指定用于身份验证的项目 ID。也就是说,当我们调用 getGoogleSheetClient() 函数时,它将读取您的客户端秘密文件并根据其中的数据启动身份验证。

身份验证成功后,它将返回一个已验证的 sheets.Service 对象,您可以使用它来读取和写入谷歌表格。您只需使用 sheetsService.Spreadsheets.Values.Update()sheetsService.Spreadsheets.Values.Get() 函数等谷歌 Sheets API 函数即可。

获取加密货币价格数据

现在,我们准备获取加密货币价格数据。CoinMarketCap API 是使用 REST API 架构构建的。我们将使用 Go 的内置网络库来发送 HTTP 请求并读取响应。

func getCoinsData() ([][]string, error) {
    url := "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?start=1&limit=100&convert=USD"
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return nil, err
    }
    
    req.Header.Set("Accepts", "application/json")
    req.Header.Add("X-CMC_PRO_API_KEY", "your-coinmarketcap-api-key")

    res, err := http.DefaultClient.Do(req)
    if err != nil {
        return nil, err
    }
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        return nil, err
    }

    var result CoinsResult
    json.Unmarshal([]byte(body), &result)

    // Extract the data
    var data [][]string
    for _, coin := range result.Data {
        data = append(data, []string{
            coin.Symbol,
            strconv.FormatFloat(coin.Quote.USD.Price, 'f', -1, 64)})
    }
    return data, nil
}

在这里,我们使用 http.NewRequest() 函数来创建一个请求对象。我们设置请求的 urlheader,其中 X-CMC_PRO_API-KEY 头字段是必须要填的,您需要将 your-coinmarketcap-api-key 替换为您的密钥。

然后,我们使用 http.DefaultClient.Do() 函数来发送请求和读取内容。响应的数据是一个字节数组,我们使用 json.Unmarshal() 函数将其转换为一个结构体。

将数据导入到谷歌表格

最后一步是将数据导入到谷歌表格中。我们需要编写一个函数来创建一个新的工作表,并将数据写入它。

func writeToGoogleSheet(values [][]string) error {
    // Get the Google Sheets client
    sheetsService, err := getGoogleSheetClient()
    if err != nil {
        return fmt.Errorf("Unable to get Google Sheets client: %v", err)
    }

    // Create the new sheet
    spreadsheet := &sheets.Spreadsheet{}
    spreadsheet.Properties = &sheets.SpreadsheetProperties{
        Title: "Coins Prices",
    }

    spreadsheet, err = sheetsService.Spreadsheets.Create(spreadsheet).Do()
    if err != nil {
        return fmt.Errorf("Unable to create new sheet: %v", err)
    }

    // Add the data to the new sheet
    valueRange := &sheets.ValueRange{}
    valueRange.Values = values

    _, err = sheetsService.Spreadsheets.Values.Update(
        spreadsheet.SpreadsheetId, "A1", valueRange).ValueInputOption("RAW").Do()

    if err != nil {
        return fmt.Errorf("Unable to write data to sheet: %v", err)
    }
    return nil
}

在这里,我们使用 getGoogleSheetClient() 函数获取谷歌表格服务并创建一个新工作表。我们还为该工作表设置 Title 属性。

接下来,我们构造 sheets.ValueRange 对象,并将我们获得的加密货币数据写入它。在这里,我们使用单元格 A1 作为数据的起始位置。使用 RAW 选项写入数据后,这些数据将使用原始格式进行查看和分析。

至此,该导入加密货币价格数据到谷歌表格的代码就发布完毕了
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "os"
    "strconv"

    "golang.org/x/oauth2"
    "golang.org/x/oauth2/google"
    "google.golang.org/api/sheets/v4"
)

type CoinsResult struct {
    Data []struct {
        Symbol string `json:"symbol"`
        Quote  struct {
            USD struct {
                Price float64 `json:"price"`
            } `json:"USD"`
        } `json:"quote"`
    } `json:"data"`
}

func main() {
    coins, err := getCoinsData()
    if err != nil {
        log.Fatalf("Unable to get coins data: %v", err)
    }

    err = writeToGoogleSheet(coins)
    if err != nil {
        log.Fatalf("Unable to write data to sheet: %v", err)
    }
}

func getGoogleSheetClient() (*sheets.Service, error) {
    b, err := ioutil.ReadFile("client_secret.json")
    if err != nil {
        return nil, fmt.Errorf("Unable to read client secret file: %v", err)
    }

    // If modifying these scopes, delete your previously saved client_secret.json.
    config, err := google.ConfigFromJSON(b, sheets.SpreadsheetsScope)
    if err != nil {
        return nil, fmt.Errorf("Unable to parse client secret file to config: %v", err)
    }
    client := getClient(config)

    srv, err := sheets.New(client)
    if err != nil {
        return nil, fmt.Errorf("Unable to retrieve Sheets client: %v", err)
    }
    return srv, nil
}

func getClient(config *oauth2.Config) *http.Client {
    tokFile := "token.json"
    tok, err := tokenFromFile(tokFile)
    if err != nil {
        tok = getTokenFromWeb(config)
        saveToken(tokFile, tok)
    }
    return config.Client(context.Background(), tok)
}

func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
    authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
    fmt.Printf("Go to the following link in your browser then type the "+
        "authorization code: \n%v\n", authURL)

    var authCode string
    if _, err := fmt.Scan(&authCode); err != nil {
        log.Fatalf("Unable to read authorization code: %v", err)
    }

    tok, err := config.Exchange(context.TODO(), authCode)
    if err != nil {
        log.Fatalf("Unable to retrieve token from web: %v", err)
    }
    return tok
}

func tokenFromFile(file string) (*oauth2.Token, error) {
    f, err := os.Open(file)
    if err != nil {
        return nil, err
    }
    defer f.Close()
    tok := &oauth2.Token{}
    err = json.NewDecoder(f).Decode(tok)
    return tok, err
}

func saveToken(file string, token *oauth2.Token) {
    fmt.Printf("Saving credential file to: %s\n", file)
    f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
    if err != nil {
        log.Fatalf("Unable to cache oauth token: %v", err)
    }
    defer f.Close()
    json.NewEncoder(f).Encode(token)
}

func getCoinsData() ([][]string, error) {
    url := "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?start=1&limit=100&convert=USD"
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return nil, err
    }

    req.Header.Set("Accepts", "application/json")
    req.Header.Add("X-CMC_PRO_API_KEY", "your-coinmarketcap-api-key")

    res, err := http.DefaultClient.Do(req)
    if err != nil {
        return nil, err
    }
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        return nil, err
    }

    var result CoinsResult
    json.Unmarshal([]byte(body), &result)

    // Extract the data
    var data [][]string
    for _, coin := range result.Data {
        data = append(data, []string{
            coin.Symbol,
            strconv.FormatFloat(coin.Quote.USD.Price, 'f', -1, 64)})
    }
    return data, nil
}

func writeToGoogleSheet(values [][]string) error {
    // Get the Google Sheets client
    sheetsService, err := getGoogleSheetClient()
    if err != nil {
        return fmt.Errorf("Unable to get Google Sheets client: %v", err)
    }

    // Create the new sheet
    spreadsheet := &sheets.Spreadsheet{}
    spreadsheet.Properties = &sheets.SpreadsheetProperties{
        Title: "Coins Prices",
    }

    spreadsheet, err = sheetsService.Spreadsheets.Create(spreadsheet).Do()
    if err != nil {
        return fmt.Errorf("Unable to create new sheet: %v", err)
    }

    // Add the data to the new sheet
    valueRange := &sheets.ValueRange{}
    valueRange.Values = values

    _, err = sheetsService.Spreadsheets.Values.Update(
        spreadsheet.SpreadsheetId, "A1", valueRange).ValueInputOption("RAW").Do()

    if err != nil {
        return fmt.Errorf("Unable to write data to sheet: %v", err)
    }
    return nil
}

代码片段已按markdown标明