stock.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. package markinfo
  2. import "net/http"
  3. import "bytes"
  4. import "io/ioutil"
  5. import "time"
  6. import "regexp"
  7. import "strings"
  8. import "strconv"
  9. import "errors"
  10. import "fmt"
  11. var stockName map[int]string
  12. var stockSymbol map[int64]int
  13. func getStockSymbol() error {
  14. return nil
  15. if stockSymbol != nil {
  16. return nil
  17. }
  18. stockSymbol = make(map[int64]int)
  19. stockName = make(map[int]string)
  20. for {
  21. sh, sz, err := getInstrument()
  22. if err != nil {
  23. time.Sleep(time.Second)
  24. continue
  25. }
  26. n := 0
  27. for i := 0; i < len(sh); i++ {
  28. name := sh[i]
  29. insId, err := strconv.ParseInt(name, 10, 64)
  30. if err != nil {
  31. stockSymbol = nil
  32. return err
  33. }
  34. n++
  35. stockSymbol[insId] = n
  36. stockName[n] = "sh" + name
  37. }
  38. //增加一些指数
  39. n++
  40. stockSymbol[999999] = n
  41. stockName[n] = "sh000001"
  42. n++
  43. stockSymbol[999999-1] = n
  44. stockName[n] = "sh000300"
  45. for i := 0; i < len(sz); i++ {
  46. name := sz[i]
  47. insId, err := strconv.ParseInt(name, 10, 64)
  48. if err != nil {
  49. stockSymbol = nil
  50. return err
  51. }
  52. n++
  53. stockSymbol[insId] = n
  54. stockName[n] = "sz" + name
  55. }
  56. break
  57. }
  58. return nil
  59. }
  60. var symbolurl = "http://quote.eastmoney.com/stock_list.html"
  61. func getInstrument() ([]string, []string, error) {
  62. resp, err := http.Get(symbolurl)
  63. if err != nil {
  64. return nil, nil, err
  65. }
  66. defer resp.Body.Close()
  67. data, err := ioutil.ReadAll(resp.Body)
  68. if err != nil {
  69. return nil, nil, err
  70. }
  71. symbolcontent := bytes.SplitN(data, []byte(`<div id="quotesearch">`), 2)
  72. if len(symbolcontent) != 2 {
  73. return nil, nil, errors.New("no symbolcontent-0")
  74. }
  75. symbolcontent = bytes.SplitN(symbolcontent[1], []byte("</ul>"), 3)
  76. if len(symbolcontent) != 3 {
  77. return nil, nil, errors.New("no symbolcontent-1")
  78. }
  79. //sh symbol list
  80. shlist, err := getli(symbolcontent[0])
  81. if err != nil {
  82. return nil, nil, err
  83. }
  84. //sz
  85. szlist, err := getli(symbolcontent[1])
  86. if err != nil {
  87. return nil, nil, err
  88. }
  89. var sh []string
  90. for i := 0; i < len(shlist); i++ {
  91. shstock := string(shlist[i])
  92. sb := getsymbol(shstock)
  93. if sb == "" {
  94. continue
  95. }
  96. sh = append(sh, sb)
  97. }
  98. var sz []string
  99. for i := 0; i < len(szlist); i++ {
  100. szstock := string(szlist[i])
  101. sb := getsymbol(szstock)
  102. if sb == "" {
  103. continue
  104. }
  105. sz = append(sz, sb)
  106. }
  107. return sh, sz, nil
  108. }
  109. func getli(data []byte) ([][]byte, error) {
  110. return matchTag(data, "li")
  111. }
  112. func getsymbol(data string) string {
  113. data = stripTags(data)
  114. o, _, err := strRange(data, "(", ")", 0)
  115. if err != nil {
  116. return ""
  117. }
  118. 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"{
  119. return o
  120. }
  121. return ""
  122. }
  123. func strRange(html string, start string, end string, offset int) (string, int, error) {
  124. istart := strings.SplitN(html, start, 2)
  125. if len(istart) != 2 {
  126. return "", 0, errors.New("start string not found")
  127. }
  128. if offset > 0 {
  129. istart[1] = istart[1][offset:]
  130. }
  131. iend := strings.SplitN(istart[1], end, 2)
  132. if len(iend) != 2{
  133. return "", 0, errors.New("end string not found")
  134. }
  135. return iend[0], len(istart[0]) + len(iend[0]), nil
  136. }
  137. func matchTag(html []byte, tagname string) ([][]byte, error) {
  138. exp, err := regexp.Compile("(?i)<"+tagname+"[^>]*>(.*?)</"+tagname+">")
  139. if err != nil {
  140. return nil, err
  141. }
  142. matched := exp.FindAllSubmatch(html, -1)
  143. if len(matched) == 0 {
  144. return nil, fmt.Errorf("tagname=%s not matched", tagname)
  145. }
  146. ret := make([][]byte, len(matched))
  147. for i := 0; i < len(ret); i++ {
  148. ret[i] = matched[i][1]
  149. }
  150. return ret, nil
  151. }
  152. var tagsRegexp = regexp.MustCompile("<[^>]+>")
  153. func stripTags(html string) string {
  154. return tagsRegexp.ReplaceAllString(html, "")
  155. }