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+"[^>]*>(.*?)"+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, "")
}