package mainimport ("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 []StockDatapage := 1for {fmt.Printf("正在获取第 %d 页数据...\n", page)// 构建API URLurl := 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 []StockDataerr = 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")
}