func GetStudent(d *goquery.Document, rollno int) (s Student, ok bool) { //sanity on document // if v := d.Find(".titlehead").Children().Text(); v != "JEE (Advanced) - 2013 Result" { // return Student{}, false // } dtext := strings.Trim(d.Text(), " ") dfields := strings.Fields(dtext) for _, v := range dfields { s.Plaintext += v + " " } s.Plaintext = strings.Trim(s.Plaintext, " ") if isInvalid(dtext) { return s, false } ok = true s.Rollno = rollno s.Region = s.Rollno / 10000 if !isSelected(dtext) { return } s.Selected = true s.Rank, _ = strconv.Atoi(d.Find(".style7").First().Text()) text, _ := d.Find(".titlehead").First().Parent().Next().Children().Children().First().Html() tokens := strings.Split(text, "<br/>") nameToks := strings.Fields(tokens[1]) nameToks = nameToks[2:len(nameToks)] for _, v := range nameToks { s.Name += v + " " } s.Name = strings.Trim(s.Name, " ") s.Q = GetQuota(dtext) return }
func markTopImage(d *goquery.Document) bool { changed := false totalTextCount := len(d.Text()) img := d.Find("img") if img.Length() == 0 { return changed } if totalTextCount == 0 { img.AddClass("top-image") changed = true } else { afterTextCount := len(img.NextAll().Text()) // Add any text-node siblings of the image for n := img.Get(0).NextSibling; n != nil; n = n.NextSibling { if n.Type == html.TextNode { afterTextCount += len(n.Data) } } img.Parents().Each(func(i int, s *goquery.Selection) { afterTextCount += len(s.NextAll().Text()) }) if totalTextCount-afterTextCount <= afterTextCount { img.AddClass("top-image") changed = true } } return changed }
func parseStatusPage(s *goquery.Document) (*Status, error) { c := s.Find(".container").First() t := c.Find("div").First().Text() if t != ">証拠金状況照会<" { return nil, fmt.Errorf("cannot open \"証拠金状況照会\", but %#v", t) } results := []string{} c.Find("hr").First().NextUntil("hr").Each( func(_ int, s *goquery.Selection) { results = append(results, s.Text()) }) orig := map[string]string{} for i := 0; i+1 < len(results); i += 2 { k := strings.TrimSpace(strings.Replace(results[i], ":", "", -1)) v := strings.TrimSpace(results[i+1]) orig[k] = v } return &Status{ ActualDeposit: parsePrice(orig["有効証拠金額"]), NecessaryDeposit: parsePrice(orig["必要証拠金額"]), }, nil }
func parsePositionDetailsPage(s *goquery.Document) (*Position, error) { c := s.Find(".container").First() t := c.Find("div").First().Text() if t != ">ポジション情報(詳細)<" { return nil, fmt.Errorf("cannot open \"ポジション情報(詳細)\", but %#v", t) } position := &Position{} // タイトル行の削除 c.Find("hr").First().Next().PrevAll().Remove() // 通貨名の設定 position.Currency = c.Find("div").First().Text() // 通貨名行の削除 c.Find("hr").First().Next().PrevAll().Remove() // メニューの削除 c.Find("hr").First().Prev().NextAll().Remove() results := []string{} c.Find("div").Each(func(_ int, s *goquery.Selection) { results = append(results, s.Text()) }) orig := map[string]string{} for i := 0; i+1 < len(results); i += 2 { k := strings.TrimSpace(strings.Replace(results[i], ":", "", -1)) v := strings.TrimSpace(results[i+1]) orig[k] = v } position.PositionId = orig["ポジション番号"] position.TransactionTime = orig["約定日時"] if orig["売買"] == "売" { position.Side = "sell" } else if orig["売買"] == "買" { position.Side = "buy" } rate, err := strconv.ParseFloat(orig["約定価格"], 64) if err != nil { return nil, fmt.Errorf("invalid transaction rate: %v", err) } position.TransactionRate = rate lot, err := strconv.ParseInt(orig["残Lot数"], 10, 64) position.Amount = lot * 1000 return position, nil }
func findProductsOnSearchPage(doc *goquery.Document, c chan<- *products.ProductUrls) int { if strings.Contains(doc.Text(), "Robot Check") { fmt.Println("We're being blocked by captcha :(") os.Exit(2) } numberOfProductsFound := 0 doc.Find(".s-access-image").Each(func(i int, image *goquery.Selection) { product, error := extractProduct(image) if error == nil { numberOfProductsFound++ c <- &product } else { log.Printf("Unable to extract product from goquery selection: %v\n", error) } }) return numberOfProductsFound }
func parseOrderDetailsPage(s *goquery.Document) (*Order, error) { c := s.Find(".container").First() t := c.Find("div").First().Text() if t != ">注文情報(詳細)<" { return nil, fmt.Errorf("cannot open \"注文情報(詳細)\", but %#v", t) } o := &Order{} // タイトル行の削除 c.Find("hr").First().Next().PrevAll().Remove() c.Find("a").Each(func(_ int, s *goquery.Selection) { href, _ := s.Attr("href") // 取消リンク if strings.HasPrefix(href, "../otc/CT01.html?") { u, err := url.Parse(href) if err != nil || u.RawQuery == "" { return } v, err := url.ParseQuery(u.RawQuery) if err != nil { return } o.OrderId = v.Get("order_id") o.OrderMethod = v.Get("order_method") } // 指定決済リンク if strings.HasPrefix(href, "../common/I124.html?") { u, err := url.Parse(href) if err != nil || u.RawQuery == "" { return } v, err := url.ParseQuery(u.RawQuery) if err != nil { return } o.PositionId = v.Get("position_id") } }) // メニューの削除 c.Find("hr").First().Prev().NextAll().Remove() results := []string{} c.Find("div").Each(func(_ int, s *goquery.Selection) { results = append(results, s.Text()) }) orig := map[string]string{} for i := 0; i+1 < len(results); i += 2 { k := strings.TrimSpace(strings.Replace(results[i], ":", "", -1)) v := strings.TrimSpace(results[i+1]) orig[k] = v } o.Currency = orig["通貨ペア"] lot, err := strconv.ParseInt(orig["注文Lot数"], 10, 64) if err != nil { return nil, err } o.Amount = lot * 1000 if orig["売買"] == "売" { o.Side = "sell" } else if orig["売買"] == "買" { o.Side = "buy" } else { return nil, fmt.Errorf("invalid value for 売買: %#v", orig["売買"]) } if orig["執行条件"] == "指値" { o.IsStop = false } else if orig["執行条件"] == "逆指" { o.IsStop = true } else { return nil, fmt.Errorf("invalid value for 執行条件: %#v", orig["執行条件"]) } o.Price, err = strconv.ParseFloat(orig["指定レート"], 64) if err != nil { return nil, err } if orig["注文区分"] == "指定決済" { o.IsSettlement = true } else if orig["注文区分"] == "売買" { o.IsSettlement = false } else { return nil, fmt.Errorf("invalid value for 注文区分: %#v", orig["注文区分"]) } return o, nil }