go语言访问新浪股票

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"time"
)

// StockData 定义股票数据结构
type StockData struct {
	Symbol        string `json:"symbol"`        // 股票符号
	Code          string `json:"code"`          // 股票代码
	Name          string `json:"name"`          // 股票名称
	Trade         any    `json:"trade"`         // 当前价格
	PriceChange   any    `json:"pricechange"`   // 价格变动
	ChangePercent any    `json:"changepercent"` // 涨跌幅
	Buy           any    `json:"buy"`           // 买入价
	Sell          any    `json:"sell"`          // 卖出价
	Settlement    any    `json:"settlement"`    // 结算价
	Open          any    `json:"open"`          // 开盘价
	High          any    `json:"high"`          // 最高价
	Low           any    `json:"low"`           // 最低价
	Volume        any    `json:"volume"`        // 成交量
	Amount        any    `json:"amount"`        // 成交额
	TickTime      string `json:"ticktime"`      //
	PER           any    `json:"per"`           // 市盈率
	PB            any    `json:"pb"`            // 市净率
	Mktcap        any    `json:"mktcap"`        // 总市值
	Nmcap         any    `json:"nmcap"`         // 流通市值
	TurnoverRatio any    `json:"turnoverratio"` // 换手率
}

// APIResponse API响应结构
type APIResponse struct {
	Data []StockData `json:"data"`
}

func main() {
	fmt.Println("开始获取新浪财经股票数据...")

	// 存储所有股票数据
	var allStocks []StockData
	page := 1

	for {
		fmt.Printf("正在获取第 %d 页数据...\n", page)

		// 构建API URL
		url := fmt.Sprintf("https://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeData?page=%d&num=100&sort=symbol&asc=0&node=hs_a", page)

		// 发送HTTP请求
		resp, err := http.Get(url)
		if err != nil {
			log.Printf("第 %d 页请求失败: %v", page, err)
			break
		}

		// 读取响应体
		body, err := io.ReadAll(resp.Body)
		resp.Body.Close()
		if err != nil {
			log.Printf("读取第 %d 页响应失败: %v", page, err)
			break
		}

		// 检查是否返回空数组
		if string(body) == "[]" {
			fmt.Printf("第 %d 页返回空数组,数据获取完成\n", page)
			break
		}

		// 解析JSON数据
		var stocks []StockData
		err = json.Unmarshal(body, &stocks)
		if err != nil {
			log.Printf("解析第 %d 页JSON失败: %v", page, err)
			log.Printf("响应内容: %s", string(body))
			break
		}

		// 检查是否获取到数据
		if len(stocks) == 0 {
			fmt.Printf("第 %d 页没有数据,数据获取完成\n", page)
			break
		}

		// 添加到总数据中
		allStocks = append(allStocks, stocks...)
		fmt.Printf("第 %d 页获取到 %d 条数据,累计 %d 条数据\n", page, len(stocks), len(allStocks))

		// 翻页
		page++

		// 添加延迟,避免请求过于频繁
		time.Sleep(500 * time.Millisecond)
	}

	// 输出统计信息
	fmt.Printf("\n数据获取完成!总共获取到 %d 条股票数据\n", len(allStocks))

	// 显示前10条数据作为示例
	if len(allStocks) > 0 {
		fmt.Println("\n前10条股票数据示例:")
		fmt.Println("========================================================================================================")
		fmt.Printf("%-10s %-20s %-8s %-8s %-8s %-12s %-12s\n",
			"代码", "名称", "当前价", "涨跌", "涨跌幅", "成交量", "成交额")
		fmt.Println("========================================================================================================")

		for i := 0; i < 10 && i < len(allStocks); i++ {
			stock := allStocks[i]
			fmt.Printf("%-10s %-20s %-8s %-8s %-8s %-12s %-12s\n",
				stock.Symbol, stock.Name, stock.Trade, stock.PriceChange,
				stock.ChangePercent, stock.Volume, stock.Amount)
		}
	}

	// 保存数据到文件
	saveToFile(allStocks)
}

// saveToFile 将数据保存到JSON文件
func saveToFile(stocks []StockData) {
	fileData, err := json.MarshalIndent(stocks, "", "  ")
	if err != nil {
		log.Printf("序列化数据失败: %v", err)
		return
	}

	err = os.WriteFile("stock_data.json", fileData, 0644)
	if err != nil {
		log.Printf("保存文件失败: %v", err)
		return
	}

	fmt.Printf("\n数据已保存到 stock_data.json 文件\n")
}
posted @ 2025-11-04 18:31  卓能文  阅读(6)  评论(0)    收藏  举报