package markinfo import "net/http" import "bytes" import "io/ioutil" import "time" import "regexp" import "strings" import "strconv" import "errors" import "fmt" var stockName map[int]string var stockSymbol map[int64]int func getStockSymbol() error { return nil if stockSymbol != nil { return nil } stockSymbol = make(map[int64]int) stockName = make(map[int]string) for { sh, sz, err := getInstrument() if err != nil { time.Sleep(time.Second) continue } n := 0 for i := 0; i < len(sh); i++ { name := sh[i] insId, err := strconv.ParseInt(name, 10, 64) if err != nil { stockSymbol = nil return err } n++ stockSymbol[insId] = n stockName[n] = "sh" + name } //增加一些指数 n++ stockSymbol[999999] = n stockName[n] = "sh000001" n++ stockSymbol[999999-1] = n stockName[n] = "sh000300" for i := 0; i < len(sz); i++ { name := sz[i] insId, err := strconv.ParseInt(name, 10, 64) if err != nil { stockSymbol = nil return err } n++ stockSymbol[insId] = n stockName[n] = "sz" + name } break } return nil } var symbolurl = "http://quote.eastmoney.com/stock_list.html" func getInstrument() ([]string, []string, error) { resp, err := http.Get(symbolurl) if err != nil { return nil, nil, err } defer resp.Body.Close() data, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, nil, err } symbolcontent := bytes.SplitN(data, []byte(`
`), 2) if len(symbolcontent) != 2 { return nil, nil, errors.New("no symbolcontent-0") } symbolcontent = bytes.SplitN(symbolcontent[1], []byte(""), 3) if len(symbolcontent) != 3 { return nil, nil, errors.New("no symbolcontent-1") } //sh symbol list shlist, err := getli(symbolcontent[0]) if err != nil { return nil, nil, err } //sz szlist, err := getli(symbolcontent[1]) if err != nil { return nil, nil, err } var sh []string for i := 0; i < len(shlist); i++ { shstock := string(shlist[i]) sb := getsymbol(shstock) if sb == "" { continue } sh = append(sh, sb) } var sz []string for i := 0; i < len(szlist); i++ { szstock := string(szlist[i]) sb := getsymbol(szstock) if sb == "" { continue } sz = append(sz, sb) } return sh, sz, nil } func getli(data []byte) ([][]byte, error) { return matchTag(data, "li") } func getsymbol(data string) string { data = stripTags(data) o, _, err := strRange(data, "(", ")", 0) if err != nil { return "" } if o[0:1] == "0" || o[0:1] == "6" || o[0:3] == "900" || o[0:3] == "200" || o[0:3] == "502" || o[0:3] == "300"{ return o } return "" } func strRange(html string, start string, end string, offset int) (string, int, error) { istart := strings.SplitN(html, start, 2) if len(istart) != 2 { return "", 0, errors.New("start string not found") } if offset > 0 { istart[1] = istart[1][offset:] } iend := strings.SplitN(istart[1], end, 2) if len(iend) != 2{ return "", 0, errors.New("end string not found") } return iend[0], len(istart[0]) + len(iend[0]), nil } func matchTag(html []byte, tagname string) ([][]byte, error) { exp, err := regexp.Compile("(?i)<"+tagname+"[^>]*>(.*?)") if err != nil { return nil, err } matched := exp.FindAllSubmatch(html, -1) if len(matched) == 0 { return nil, fmt.Errorf("tagname=%s not matched", tagname) } ret := make([][]byte, len(matched)) for i := 0; i < len(ret); i++ { ret[i] = matched[i][1] } return ret, nil } var tagsRegexp = regexp.MustCompile("<[^>]+>") func stripTags(html string) string { return tagsRegexp.ReplaceAllString(html, "") }