mirror of
https://github.com/nprasad2077/NBA_Go.git
synced 2026-09-22 14:05:13 +00:00
totals data service update
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
||||
# STEP 1 - build with CGO enabled
|
||||
FROM golang:1.22-bullseye AS builder
|
||||
FROM golang:1.24-bullseye AS builder
|
||||
|
||||
ENV CGO_ENABLED=1
|
||||
ENV GOOS=linux
|
||||
|
||||
@@ -33,6 +33,29 @@ func FetchPlayerTotalStats(db *gorm.DB) fiber.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
// ScrapePlayerTotalStats godoc
|
||||
// @Summary Scrape player total stats from BR website
|
||||
// @Tags PlayerTotals
|
||||
// @Param season query int true "Season (e.g. 2025)"
|
||||
// @Param isPlayoff query bool false "Whether playoffs?"
|
||||
// @Success 200 {object} map[string]string
|
||||
// @Failure 400,500 {object} map[string]string
|
||||
// @Router /api/playertotals/scrape [get]
|
||||
func ScrapePlayerTotalStats(db *gorm.DB) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
season := c.QueryInt("season", 0)
|
||||
if season == 0 {
|
||||
return c.Status(400).JSON(fiber.Map{"error":"season is required"})
|
||||
}
|
||||
isPlayoff := c.QueryBool("isPlayoff", false)
|
||||
|
||||
if err := services.FetchAndStorePlayerTotalScrapedStats(db, season, isPlayoff); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message":"scrapestore complete"})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// GetPlayerTotalStats godoc
|
||||
// @Security ApiKeyAuth
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
module github.com/nprasad2077/NBA_Go
|
||||
|
||||
go 1.22
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.24.2
|
||||
|
||||
require (
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/PuerkitoBio/goquery v1.10.3 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.3 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
@@ -41,9 +43,9 @@ require (
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.51.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/net v0.39.0 // indirect
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo=
|
||||
github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
@@ -9,6 +11,8 @@ github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaW
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
|
||||
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
@@ -32,6 +36,7 @@ github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/
|
||||
github.com/gofiber/fiber/v2 v2.32.0/go.mod h1:CMy5ZLiXkn6qwthrl03YMyW1NLfj0rhxz2LKl4t7ZTY=
|
||||
github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI=
|
||||
github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
@@ -112,23 +117,48 @@ github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdI
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -138,25 +168,52 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
// "strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
)
|
||||
|
||||
func main() {
|
||||
season := flag.Int("season", 0, "NBA season year (e.g. 2024)")
|
||||
outPath := flag.String("out", "", "output CSV file path (default: stdout)")
|
||||
flag.Parse()
|
||||
|
||||
if *season == 0 {
|
||||
fmt.Fprintln(os.Stderr, "❌ must provide -season, e.g. -season=2024")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("https://www.basketball-reference.com/leagues/NBA_%d_advanced.html", *season)
|
||||
fmt.Println("Fetching:", url)
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "HTTP error:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
doc, err := goquery.NewDocumentFromReader(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Parse error:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// --- Extract headers ---
|
||||
var headers []string
|
||||
doc.Find("#div_advanced table#advanced thead tr th").EachWithBreak(func(i int, s *goquery.Selection) bool {
|
||||
// grab first 29 columns, then we'll append our own PlayerID
|
||||
text := strings.TrimSpace(s.Text())
|
||||
if i < 29 {
|
||||
headers = append(headers, text)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
headers = append(headers, "Player-additional")
|
||||
|
||||
// --- Extract data rows ---
|
||||
var rows [][]string
|
||||
doc.Find("#div_advanced table#advanced tbody tr").Each(func(_ int, row *goquery.Selection) {
|
||||
if row.HasClass("thead") { // skip repeated headers
|
||||
return
|
||||
}
|
||||
// rank in <th>
|
||||
vals := []string{strings.TrimSpace(row.Find("th").Text())}
|
||||
row.Find("td").Each(func(__ int, cell *goquery.Selection) {
|
||||
vals = append(vals, strings.TrimSpace(cell.Text()))
|
||||
})
|
||||
if id, ok := row.Find("td[data-append-csv]").Attr("data-append-csv"); ok {
|
||||
vals = append(vals, id)
|
||||
rows = append(rows, vals)
|
||||
}
|
||||
})
|
||||
|
||||
// open writer
|
||||
var w *csv.Writer
|
||||
if *outPath != "" {
|
||||
f, err := os.Create(*outPath)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Could not create file:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer f.Close()
|
||||
w = csv.NewWriter(f)
|
||||
} else {
|
||||
w = csv.NewWriter(os.Stdout)
|
||||
}
|
||||
// write header + rows
|
||||
w.Write(headers)
|
||||
for _, r := range rows {
|
||||
w.Write(r)
|
||||
}
|
||||
w.Flush()
|
||||
if err := w.Error(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "CSV write error:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// also print first 5 records to console
|
||||
fmt.Println("\nFirst 5 rows:")
|
||||
for i := 0; i < len(rows) && i < 5; i++ {
|
||||
fmt.Println(rows[i])
|
||||
}
|
||||
fmt.Printf("\n✅ Wrote %d rows\n", len(rows))
|
||||
}
|
||||
@@ -10,5 +10,6 @@ func RegisterPlayerTotalRoutes(app *fiber.App, db *gorm.DB) {
|
||||
api := app.Group("/api/playertotals")
|
||||
|
||||
api.Get("/fetch", controllers.FetchPlayerTotalStats(db))
|
||||
api.Get("/scrape", controllers.ScrapePlayerTotalStats(db))
|
||||
api.Get("/", controllers.GetPlayerTotalStats(db))
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/csv"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
func main() {
|
||||
playerID := flag.String("playerid", "", "Basketball-Reference player ID (e.g. derozde01)")
|
||||
playerName := flag.String("playername", "", "Player name for file naming (e.g. \"DeMar DeRozan\")")
|
||||
startSeason := flag.Int("start", 0, "Recent start season (e.g. 2024)")
|
||||
endSeason := flag.Int("end", 0, "Rookie/end season (e.g. 2021)")
|
||||
outDir := flag.String("outdir", "", "If set, write CSV files into this directory; otherwise stdout")
|
||||
flag.Parse()
|
||||
|
||||
if *playerID == "" || *playerName == "" || *startSeason == 0 || *endSeason == 0 {
|
||||
fmt.Fprintln(os.Stderr, "❌ must provide -playerid, -playername, -start and -end")
|
||||
os.Exit(1)
|
||||
}
|
||||
if *startSeason < *endSeason {
|
||||
fmt.Fprintln(os.Stderr, "❌ start must be >= end")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for season := *startSeason; season >= *endSeason; season-- {
|
||||
url := fmt.Sprintf(
|
||||
"https://www.basketball-reference.com/players/%s/%s/shooting/%d",
|
||||
(*playerID)[:1], *playerID, season,
|
||||
)
|
||||
fmt.Println("Fetching:", url)
|
||||
|
||||
// Build a real-browser request
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Request creation error for season %d: %v\n", season, err)
|
||||
continue
|
||||
}
|
||||
req.Header.Set("User-Agent",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "+
|
||||
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
|
||||
)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "HTTP error for %d: %v\n", season, err)
|
||||
continue
|
||||
}
|
||||
bodyBytes, err := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Read error for %d: %v\n", season, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse the full HTML to find the commented-out shot-chart block
|
||||
shotHTML := extractCommentedShotChart(bodyBytes)
|
||||
if shotHTML == "" {
|
||||
fmt.Fprintf(os.Stderr, "❌ no shot‐chart comment found for %d\n", season)
|
||||
continue
|
||||
}
|
||||
|
||||
// Now parse that snippet
|
||||
doc, err := goquery.NewDocumentFromReader(strings.NewReader(shotHTML))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Parse error for %d: %v\n", season, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// grab the shot-wrapper inside the commented HTML
|
||||
wrapper := doc.Find("div#div_shot-chart div#shot-wrapper")
|
||||
if wrapper.Length() == 0 {
|
||||
fmt.Fprintf(os.Stderr, "❌ no shot‐wrapper found in comment for %d\n", season)
|
||||
continue
|
||||
}
|
||||
|
||||
shots := wrapper.Find("div.tooltip.make, div.tooltip.miss")
|
||||
var rows [][]string
|
||||
shots.Each(func(_ int, s *goquery.Selection) {
|
||||
style, _ := s.Attr("style")
|
||||
tip, _ := s.Attr("tip")
|
||||
|
||||
// parse top/left
|
||||
parts := strings.Split(style, ";")
|
||||
topVal := parsePx(parts[0])
|
||||
leftVal:= parsePx(parts[1])
|
||||
|
||||
tipParts := strings.Split(tip, "<br>")
|
||||
// date, team code, opponent
|
||||
dateSegs := strings.SplitN(tipParts[0], ", ", 3)
|
||||
date := dateSegs[0] + "," + dateSegs[1]
|
||||
team := ""
|
||||
if len(dateSegs) == 3 {
|
||||
team = dateSegs[2]
|
||||
}
|
||||
opponent := ""
|
||||
if parts := strings.SplitN(tipParts[0], " at ", 2); len(parts) == 2 {
|
||||
opponent = parts[1]
|
||||
} else if parts := strings.SplitN(tipParts[0], " vs ", 2); len(parts) == 2 {
|
||||
opponent = parts[1]
|
||||
}
|
||||
|
||||
// quarter & time
|
||||
qt := strings.SplitN(tipParts[1], ",", 2)
|
||||
quarter := qt[0]
|
||||
timeRem := strings.Fields(qt[1])[0]
|
||||
|
||||
// result, shot type, distance
|
||||
rt := strings.Fields(tipParts[2])
|
||||
result := (rt[0] == "Made")
|
||||
shotType := rt[1]
|
||||
distance := parseInt(rt[len(rt)-2])
|
||||
|
||||
// scores
|
||||
last := strings.Fields(tipParts[3])
|
||||
sc := strings.Split(last[len(last)-1], "-")
|
||||
teamScore := parseInt(sc[0])
|
||||
opponentScore := parseInt(sc[1])
|
||||
lead := teamScore > opponentScore
|
||||
|
||||
rows = append(rows, []string{
|
||||
*playerName,
|
||||
fmt.Sprint(topVal),
|
||||
fmt.Sprint(leftVal),
|
||||
date,
|
||||
quarter,
|
||||
timeRem,
|
||||
fmt.Sprint(result),
|
||||
shotType,
|
||||
fmt.Sprint(distance),
|
||||
fmt.Sprint(lead),
|
||||
fmt.Sprint(teamScore),
|
||||
fmt.Sprint(opponentScore),
|
||||
opponent,
|
||||
team,
|
||||
fmt.Sprint(season),
|
||||
*playerID,
|
||||
})
|
||||
})
|
||||
|
||||
headers := []string{
|
||||
"playerName","top","left","date","qtr","timeRemaining",
|
||||
"result","shotType","distanceFt","lead",
|
||||
"teamScore","opponentTeamScore","opponent","team","season","playerId",
|
||||
}
|
||||
|
||||
var w *csv.Writer
|
||||
if *outDir != "" {
|
||||
os.MkdirAll(*outDir, 0755)
|
||||
fname := filepath.Join(*outDir,
|
||||
fmt.Sprintf("%s_%d_shotchart.csv", *playerID, season),
|
||||
)
|
||||
f, err := os.Create(fname)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not create %s: %v\n", fname, err)
|
||||
continue
|
||||
}
|
||||
defer f.Close()
|
||||
w = csv.NewWriter(f)
|
||||
fmt.Printf("→ Writing %d rows to %s\n", len(rows), fname)
|
||||
} else {
|
||||
w = csv.NewWriter(os.Stdout)
|
||||
}
|
||||
|
||||
w.Write(headers)
|
||||
for _, r := range rows {
|
||||
w.Write(r)
|
||||
}
|
||||
w.Flush()
|
||||
if err := w.Error(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "CSV error: %v\n", err)
|
||||
}
|
||||
|
||||
fmt.Printf("\nFirst 5 rows for %d:\n", season)
|
||||
for i := 0; i < len(rows) && i < 5; i++ {
|
||||
fmt.Println(rows[i])
|
||||
}
|
||||
fmt.Printf("✅ Season %d: %d total shots\n\n", season, len(rows))
|
||||
}
|
||||
}
|
||||
|
||||
// extractCommentedShotChart scans the HTML for a comment node containing
|
||||
// the div#div_shot-chart block, and returns its inner HTML.
|
||||
func extractCommentedShotChart(htmlBytes []byte) string {
|
||||
root, err := html.Parse(bytes.NewReader(htmlBytes))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
var found string
|
||||
var f func(*html.Node)
|
||||
f = func(n *html.Node) {
|
||||
if n.Type == html.CommentNode && strings.Contains(n.Data, `id="div_shot-chart"`) {
|
||||
found = n.Data
|
||||
return
|
||||
}
|
||||
for c := n.FirstChild; c != nil && found == ""; c = c.NextSibling {
|
||||
f(c)
|
||||
}
|
||||
}
|
||||
f(root)
|
||||
return found
|
||||
}
|
||||
|
||||
func parsePx(s string) int {
|
||||
parts := strings.Split(s, ":")
|
||||
return parseInt(strings.TrimSuffix(parts[1], "px"))
|
||||
}
|
||||
|
||||
func parseInt(s string) int {
|
||||
v, _ := strconv.Atoi(strings.TrimSpace(s))
|
||||
return v
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/csv"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
)
|
||||
|
||||
func main() {
|
||||
season := flag.Int("season", 0, "NBA season year (e.g. 2024)")
|
||||
outPath := flag.String("out", "", "output CSV file path (default stdout)")
|
||||
flag.Parse()
|
||||
|
||||
if *season == 0 {
|
||||
fmt.Fprintln(os.Stderr, "❌ must provide -season")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("https://www.basketball-reference.com/playoffs/NBA_%d_totals.html", *season)
|
||||
fmt.Println("Fetching:", url)
|
||||
|
||||
// pretend to be a real browser
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Request error:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
req.Header.Set("User-Agent",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "+
|
||||
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
|
||||
)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "HTTP error:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Read error:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
doc, err := goquery.NewDocumentFromReader(bytes.NewReader(body))
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Parse error:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
table := doc.Find("table#totals_stats")
|
||||
if table.Length() == 0 {
|
||||
fmt.Fprintln(os.Stderr, "❌ could not find table with id 'totals_stats'")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Extract headers
|
||||
var headers []string
|
||||
table.Find("thead tr th").Each(func(_ int, th *goquery.Selection) {
|
||||
if stat, exists := th.Attr("data-stat"); exists && stat != "" {
|
||||
headers = append(headers, stat)
|
||||
}
|
||||
})
|
||||
// ensure player-additional
|
||||
headers = append(headers, "player-additional")
|
||||
|
||||
// Extract rows
|
||||
var rows [][]string
|
||||
table.Find("tbody tr").Each(func(_ int, tr *goquery.Selection) {
|
||||
if cl, _ := tr.Attr("class"); strings.Contains(cl, "thead") {
|
||||
return
|
||||
}
|
||||
var row []string
|
||||
var playerID string
|
||||
tr.Find("th, td").Each(func(_ int, cell *goquery.Selection) {
|
||||
row = append(row, strings.TrimSpace(cell.Text()))
|
||||
if id, ok := cell.Attr("data-append-csv"); ok {
|
||||
playerID = id
|
||||
}
|
||||
})
|
||||
if playerID != "" {
|
||||
row = append(row, playerID)
|
||||
rows = append(rows, row)
|
||||
}
|
||||
})
|
||||
|
||||
// open writer
|
||||
var w *csv.Writer
|
||||
if *outPath != "" {
|
||||
f, err := os.Create(*outPath)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Could not create file:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer f.Close()
|
||||
w = csv.NewWriter(f)
|
||||
fmt.Printf("→ Writing %d rows to %s\n", len(rows), *outPath)
|
||||
} else {
|
||||
w = csv.NewWriter(os.Stdout)
|
||||
}
|
||||
|
||||
// write CSV
|
||||
w.Write(headers)
|
||||
for _, r := range rows {
|
||||
w.Write(r)
|
||||
}
|
||||
w.Flush()
|
||||
if err := w.Error(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "CSV write error:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("First 5 rows:")
|
||||
for i := 0; i < len(rows) && i < 5; i++ {
|
||||
fmt.Println(rows[i])
|
||||
}
|
||||
fmt.Printf("✅ Wrote %d rows for season %d\n", len(rows), *season)
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
// File: NBA_Go/services/player_total_scrape_service.go
|
||||
|
||||
package services
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/nprasad2077/NBA_Go/models"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
const (
|
||||
regularURLFmt = "https://www.basketball-reference.com/leagues/NBA_%d_totals.html"
|
||||
playoffURLFmt = "https://www.basketball-reference.com/playoffs/NBA_%d_totals.html"
|
||||
)
|
||||
|
||||
// urlForSeason chooses regular vs. playoff URL.
|
||||
func urlForSeason(season int, isPlayoff bool) string {
|
||||
if isPlayoff {
|
||||
return fmt.Sprintf(playoffURLFmt, season)
|
||||
}
|
||||
return fmt.Sprintf(regularURLFmt, season)
|
||||
}
|
||||
|
||||
// FetchAndStorePlayerTotalScrapedStats scrapes BR totals (regular or playoffs)
|
||||
// and upserts into PlayerTotalStat.
|
||||
func FetchAndStorePlayerTotalScrapedStats(db *gorm.DB, season int, isPlayoff bool) error {
|
||||
url := urlForSeason(season, isPlayoff)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("User-Agent", "Mozilla/5.0 (compatible)")
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
doc, err := goquery.NewDocumentFromReader(bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
table := doc.Find("table#totals_stats")
|
||||
if table.Length() == 0 {
|
||||
return fmt.Errorf("could not find table#totals_stats")
|
||||
}
|
||||
|
||||
// 1) collect the data-stat keys in header order
|
||||
var headers []string
|
||||
table.Find("thead tr th").Each(func(i int, th *goquery.Selection) {
|
||||
if stat, ok := th.Attr("data-stat"); ok && stat != "" {
|
||||
headers = append(headers, stat)
|
||||
}
|
||||
})
|
||||
// add the appended-player column
|
||||
headers = append(headers, "player-additional")
|
||||
|
||||
// 2) iterate rows
|
||||
table.Find("tbody tr").Each(func(_ int, tr *goquery.Selection) {
|
||||
if cl, _ := tr.Attr("class"); strings.Contains(cl, "thead") {
|
||||
return // skip header rows
|
||||
}
|
||||
|
||||
cells := tr.Find("th, td")
|
||||
data := make(map[string]string, len(headers))
|
||||
var playerID string
|
||||
|
||||
cells.Each(func(i int, cell *goquery.Selection) {
|
||||
text := strings.TrimSpace(cell.Text())
|
||||
key := headers[i]
|
||||
data[key] = text
|
||||
if id, ok := cell.Attr("data-append-csv"); ok {
|
||||
playerID = id
|
||||
}
|
||||
})
|
||||
if playerID == "" {
|
||||
return
|
||||
}
|
||||
data["player-additional"] = playerID
|
||||
|
||||
// 3) map into GORM model
|
||||
stat := models.PlayerTotalStat{
|
||||
ExternalID: mustAtoi(data["rk"]),
|
||||
PlayerID: playerID,
|
||||
PlayerName: data["player"],
|
||||
Position: data["pos"],
|
||||
Age: mustAtoi(data["age"]),
|
||||
Games: mustAtoi(data["g"]),
|
||||
GamesStarted: mustAtoi(data["gs"]),
|
||||
MinutesPG: mustParseFloat(data["mp"]), // TOTAL minutes as float
|
||||
FieldGoals: mustAtoi(data["fg"]),
|
||||
FieldAttempts: mustAtoi(data["fga"]),
|
||||
FieldPercent: mustParseFloat(data["fg_pct"]),
|
||||
ThreeFG: mustAtoi(data["fg3"]),
|
||||
ThreeAttempts: mustAtoi(data["fg3a"]),
|
||||
ThreePercent: mustParseFloat(data["fg3_pct"]),
|
||||
TwoFG: mustAtoi(data["fg2"]),
|
||||
TwoAttempts: mustAtoi(data["fg2a"]),
|
||||
TwoPercent: mustParseFloat(data["fg2_pct"]),
|
||||
EffectFGPercent: mustParseFloat(data["efg_pct"]),
|
||||
FT: mustAtoi(data["ft"]),
|
||||
FTAttempts: mustAtoi(data["fta"]),
|
||||
FTPercent: mustParseFloat(data["ft_pct"]),
|
||||
OffensiveRB: mustAtoi(data["orb"]),
|
||||
DefensiveRB: mustAtoi(data["drb"]),
|
||||
TotalRB: mustAtoi(data["trb"]),
|
||||
Assists: mustAtoi(data["ast"]),
|
||||
Steals: mustAtoi(data["stl"]),
|
||||
Blocks: mustAtoi(data["blk"]),
|
||||
Turnovers: mustAtoi(data["tov"]),
|
||||
PersonalFouls: mustAtoi(data["pf"]),
|
||||
Points: mustAtoi(data["pts"]),
|
||||
Team: data["team_id"],
|
||||
Season: season,
|
||||
IsPlayoff: isPlayoff,
|
||||
}
|
||||
|
||||
// 4) upsert on (player_id, season, team, is_playoff)
|
||||
if err := db.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{
|
||||
{Name: "player_id"},
|
||||
{Name: "season"},
|
||||
{Name: "team"},
|
||||
{Name: "is_playoff"},
|
||||
},
|
||||
DoUpdates: clause.AssignmentColumns([]string{
|
||||
"external_id", "player_name", "position", "age",
|
||||
"games", "games_started", "minutes_pg",
|
||||
"field_goals", "field_attempts", "field_percent",
|
||||
"three_fg", "three_attempts", "three_percent",
|
||||
"two_fg", "two_attempts", "two_percent",
|
||||
"effect_fg_percent",
|
||||
"ft", "ft_attempts", "ft_percent",
|
||||
"offensive_rb", "defensive_rb", "total_rb",
|
||||
"assists", "steals", "blocks", "turnovers",
|
||||
"personal_fouls", "points",
|
||||
}),
|
||||
}).Create(&stat).Error; err != nil {
|
||||
log.Printf("Failed upsert for %s: %v", stat.PlayerID, err)
|
||||
}
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// mustAtoi parses integer or returns 0
|
||||
func mustAtoi(s string) int {
|
||||
i, _ := strconv.Atoi(s)
|
||||
return i
|
||||
}
|
||||
|
||||
// mustParseFloat parses float or returns 0.0
|
||||
func mustParseFloat(s string) float64 {
|
||||
f, _ := strconv.ParseFloat(s, 64)
|
||||
return f
|
||||
}
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
ranker,player,pos,age,team_id,g,gs,mp,fg,fga,fg_pct,fg3,fg3a,fg3_pct,fg2,fg2a,fg2_pct,efg_pct,ft,fta,ft_pct,orb,drb,trb,ast,stl,blk,tov,pf,pts,player-additional
|
||||
1,Precious Achiuwa,C,25,NYK,3,0,12,3,6,.500,0,0,,3,6,.500,.500,0,1,.000,1,2,3,0,0,0,0,1,6,achiupr01
|
||||
2,Steven Adams,C,31,HOU,7,0,155,12,20,.600,0,0,,12,20,.600,.600,16,30,.533,23,23,46,4,3,8,5,7,40,adamsst01
|
||||
3,Bam Adebayo,C,27,MIA,4,4,153,28,64,.438,7,21,.333,21,43,.488,.492,7,11,.636,16,28,44,17,4,1,12,9,70,adebaba01
|
||||
4,Santi Aldama,PF,24,MEM,4,1,122,21,44,.477,10,24,.417,11,20,.550,.591,0,0,,2,22,24,7,0,1,5,7,52,aldamsa01
|
||||
5,Nickeil Alexander-Walker,SG,26,MIN,9,0,175,21,59,.356,10,33,.303,11,26,.423,.441,11,12,.917,2,12,14,20,4,3,14,14,63,alexani01
|
||||
6,Jarrett Allen,C,26,CLE,8,8,231,40,55,.727,0,0,,40,55,.727,.727,32,33,.970,20,52,72,12,12,8,15,14,112,allenja01
|
||||
7,Kyle Anderson,SF,31,MIA,2,0,14,0,2,.000,0,0,,0,2,.000,.000,0,0,,0,1,1,1,0,0,1,1,0,anderky01
|
||||
8,Giannis Antetokounmpo,PF,30,MIL,5,5,188,60,99,.606,1,5,.200,59,94,.628,.611,44,63,.698,19,58,77,33,5,5,23,12,165,antetgi01
|
||||
9,Cole Anthony,PG,24,ORL,5,0,51,4,14,.286,0,6,.000,4,8,.500,.286,3,4,.750,3,4,7,6,0,1,9,12,11,anthoco01
|
||||
10,OG Anunoby,PF,27,NYK,10,10,407,57,134,.425,24,62,.387,33,72,.458,.515,22,25,.880,13,30,43,11,20,9,17,26,160,anunoog01
|
||||
11,Marvin Bagley III,PF,25,MEM,2,0,28,8,9,.889,1,1,1.000,7,8,.875,.944,0,0,,2,4,6,0,2,1,3,3,17,baglema01
|
||||
12,Paolo Banchero,PF,22,ORL,5,5,197,54,124,.435,12,27,.444,42,97,.433,.484,27,41,.659,12,30,42,21,3,4,15,18,147,banchpa01
|
||||
13,Desmond Bane,SG,26,MEM,4,4,139,20,63,.317,7,32,.219,13,31,.419,.373,14,15,.933,5,22,27,13,3,2,15,9,61,banede01
|
||||
14,Nicolas Batum,PF,36,LAC,7,0,172,13,33,.394,13,33,.394,0,0,,.591,0,0,,4,23,27,14,6,12,3,13,39,batumni01
|
||||
15,Malik Beasley,SG,28,DET,6,0,163,28,75,.373,20,59,.339,8,16,.500,.507,8,8,1.000,1,14,15,7,3,1,7,10,84,beaslma01
|
||||
16,Goga Bitadze,C,25,ORL,3,0,11,1,1,1.000,0,0,,1,1,1.000,1.000,0,0,,0,3,3,1,0,1,0,6,2,bitadgo01
|
||||
17,Anthony Black,PG,21,ORL,5,0,89,15,37,.405,2,13,.154,13,24,.542,.432,9,13,.692,10,12,22,0,4,1,2,8,41,blackan01
|
||||
18,Bogdan Bogdanović,SG,32,LAC,7,0,117,16,44,.364,7,24,.292,9,20,.450,.443,6,7,.857,5,15,20,15,3,0,11,25,45,bogdabo01
|
||||
19,Tony Bradley,C,27,IND,4,0,16,0,1,.000,0,0,,0,1,.000,.000,0,0,,2,4,6,2,0,0,0,0,0,bradlto01
|
||||
20,Christian Braun,SG,23,DEN,11,11,429,49,108,.454,14,48,.292,35,60,.583,.519,15,23,.652,20,48,68,23,12,7,9,37,127,braunch01
|
||||
21,Mikal Bridges,SF,28,NYK,10,10,408,66,146,.452,16,55,.291,50,91,.549,.507,6,7,.857,9,44,53,28,21,10,19,20,154,bridgmi01
|
||||
22,Dillon Brooks,SF,29,HOU,7,7,206,28,63,.444,10,29,.345,18,34,.529,.524,20,24,.833,9,13,22,9,5,2,9,27,86,brookdi01
|
||||
23,Jaylen Brown,SF,28,BOS,9,9,333,69,158,.437,15,49,.306,54,109,.495,.484,44,56,.786,11,53,64,25,9,2,30,27,197,brownja02
|
||||
24,Kobe Brown,PF,25,LAC,3,0,15,7,8,.875,1,1,1.000,6,7,.857,.938,1,1,1.000,0,1,1,4,0,0,0,0,16,brownko01
|
||||
25,Jalen Brunson,PG,28,NYK,10,10,401,103,237,.435,29,79,.367,74,158,.468,.496,66,81,.815,10,30,40,80,5,3,27,32,301,brunsja01
|
||||
26,Thomas Bryant,C,27,IND,9,0,89,5,11,.455,3,6,.500,2,5,.400,.591,5,6,.833,5,11,16,3,3,4,6,11,18,bryanth01
|
||||
27,Alec Burks,SG,33,MIA,1,1,15,2,3,.667,2,3,.667,0,0,,1.000,0,0,,0,2,2,2,0,0,0,0,6,burksal01
|
||||
28,Jimmy Butler,SF,35,GSW,10,10,355,64,141,.454,11,33,.333,53,108,.491,.493,55,69,.797,23,44,67,51,11,3,12,17,194,butleji01
|
||||
29,Kentavious Caldwell-Pope,SG,31,ORL,5,5,163,8,30,.267,6,23,.261,2,7,.286,.367,3,4,.750,1,14,15,9,7,3,2,11,25,caldwke01
|
||||
30,Vlatko Čančar,PF,27,DEN,3,0,11,0,0,,0,0,,0,0,,,0,0,,0,2,2,0,0,0,2,0,0,cancavl01
|
||||
31,Wendell Carter Jr.,C,25,ORL,5,5,162,21,40,.525,3,11,.273,18,29,.621,.563,6,10,.600,19,35,54,6,2,2,8,12,51,cartewe01
|
||||
32,Alex Caruso,SG,30,OKC,8,0,170,23,53,.434,14,34,.412,9,19,.474,.566,8,13,.615,5,18,23,25,15,6,5,15,68,carusal01
|
||||
33,Cam Christie,SG,19,LAC,3,0,13,2,3,.667,1,2,.500,1,1,1.000,.833,0,0,,0,2,2,0,1,0,1,0,5,chrisca02
|
||||
34,Jaylen Clark,SG,23,MIN,2,0,6,0,0,,0,0,,0,0,,,2,2,1.000,0,1,1,0,1,0,1,2,2,clarkja02
|
||||
35,Mike Conley,PG,37,MIN,9,9,217,17,56,.304,10,33,.303,7,23,.304,.393,8,9,.889,11,16,27,30,5,1,6,13,52,conlemi01
|
||||
36,Pat Connaughton,SG,32,MIL,3,0,14,2,8,.250,1,4,.250,1,4,.250,.313,1,2,.500,0,2,2,1,0,0,1,1,6,connapa01
|
||||
37,Torrey Craig,SF,34,BOS,3,0,8,1,1,1.000,1,1,1.000,0,0,,1.500,0,0,,0,0,0,0,1,0,1,0,3,craigto01
|
||||
38,Cade Cunningham,PG,23,DET,6,6,248,55,129,.426,5,28,.179,50,101,.495,.446,35,42,.833,6,44,50,52,11,8,32,20,150,cunnica01
|
||||
39,Stephen Curry,PG,36,GSW,8,8,281,62,130,.477,32,80,.400,30,50,.600,.600,25,28,.893,2,40,42,41,8,6,27,13,181,curryst01
|
||||
40,Tristan Da Silva,SF,23,ORL,2,0,5,0,1,.000,0,1,.000,0,0,,.000,0,0,,0,4,4,1,0,0,2,0,0,dasiltr01
|
||||
41,JD Davison,PG,22,BOS,2,0,5,0,4,.000,0,1,.000,0,3,.000,.000,0,0,,1,2,3,2,0,0,0,0,0,davisjd01
|
||||
42,Ousmane Dieng,C,21,OKC,1,0,8,0,3,.000,0,1,.000,0,2,.000,.000,2,2,1.000,0,2,2,1,0,0,0,0,2,diengou01
|
||||
43,Donte DiVincenzo,SG,28,MIN,9,0,232,24,80,.300,12,52,.231,12,28,.429,.375,7,9,.778,9,21,30,29,13,3,18,31,67,divindo01
|
||||
44,Luka Dončić,PG,25,LAL,5,5,208,47,104,.452,16,46,.348,31,58,.534,.529,41,46,.891,2,33,35,29,5,3,20,16,151,doncilu01
|
||||
45,Luguentz Dort,SF,25,OKC,8,8,227,19,64,.297,14,55,.255,5,9,.556,.406,9,12,.750,11,18,29,6,6,5,5,26,61,dortlu01
|
||||
46,Kris Dunn,PG,30,LAC,7,6,153,17,44,.386,10,28,.357,7,16,.438,.500,0,0,,10,14,24,9,8,4,1,18,44,dunnkr01
|
||||
47,Jalen Duren,C,21,DET,6,6,203,26,40,.650,0,0,,26,40,.650,.650,19,23,.826,26,38,64,21,2,10,10,26,71,durenja01
|
||||
48,Tari Eason,PF,23,HOU,7,0,132,21,44,.477,7,19,.368,14,25,.560,.557,4,8,.500,7,23,30,5,8,7,10,13,53,easonta01
|
||||
49,Zach Edey,C,22,MEM,4,4,108,10,15,.667,0,0,,10,15,.667,.667,5,7,.714,11,20,31,7,0,10,6,12,25,edeyza01
|
||||
50,Anthony Edwards,SG,23,MIN,9,9,358,86,196,.439,30,82,.366,56,114,.491,.515,41,55,.745,13,60,73,47,14,5,16,17,243,edwaran01
|
||||
51,Drew Eubanks,C,27,LAC,3,0,13,0,2,.000,0,0,,0,2,.000,.000,4,6,.667,0,1,1,0,0,0,0,2,4,eubandr01
|
||||
52,Dorian Finney-Smith,PF,31,LAL,5,1,170,12,29,.414,7,19,.368,5,10,.500,.534,0,0,,10,11,21,13,1,2,5,17,31,finnedo01
|
||||
53,Johnny Furphy,SG,20,IND,5,0,21,0,3,.000,0,2,.000,0,1,.000,.000,0,0,,1,3,4,1,0,1,0,5,0,furphjo01
|
||||
54,Darius Garland,PG,25,CLE,4,4,115,25,53,.472,10,29,.345,15,24,.625,.566,19,20,.950,1,6,7,23,2,0,10,13,79,garlada01
|
||||
55,Luka Garza,C,26,MIN,2,0,5,1,1,1.000,0,0,,1,1,1.000,1.000,0,0,,1,0,1,0,0,0,0,1,2,garzalu01
|
||||
56,Shai Gilgeous-Alexander,PG,26,OKC,8,8,293,75,172,.436,11,47,.234,64,125,.512,.468,60,70,.857,14,39,53,53,11,5,15,22,221,gilgesh01
|
||||
57,Rudy Gobert,C,32,MIN,9,9,253,26,47,.553,0,0,,26,47,.553,.553,20,34,.588,32,56,88,3,5,12,9,26,72,goberru01
|
||||
58,Jordan Goodwin,PG,26,LAL,4,0,31,1,5,.200,0,2,.000,1,3,.333,.200,1,2,.500,2,3,5,2,1,1,1,7,3,goodwjo01
|
||||
59,Aaron Gordon,PF,29,DEN,11,11,422,71,143,.497,19,46,.413,52,97,.536,.563,40,46,.870,42,41,83,28,6,5,18,31,201,gordoaa01
|
||||
60,A.J. Green,SG,25,MIL,5,1,135,18,39,.462,18,35,.514,0,4,.000,.692,1,2,.500,2,12,14,10,0,1,0,13,55,greenaj01
|
||||
61,Draymond Green,PF,34,GSW,11,11,353,38,97,.392,15,54,.278,23,43,.535,.469,8,11,.727,7,53,60,40,16,11,33,40,99,greendr01
|
||||
62,Jalen Green,SG,22,HOU,7,7,219,32,86,.372,13,44,.295,19,42,.452,.448,16,24,.667,3,35,38,20,4,2,10,6,93,greenja05
|
||||
63,Javonte Green,SG,31,CLE,6,0,39,4,10,.400,1,5,.200,3,5,.600,.450,6,6,1.000,1,8,9,2,4,0,2,2,15,greenja02
|
||||
64,Jeff Green,PF,38,HOU,3,0,5,1,3,.333,1,1,1.000,0,2,.000,.500,0,0,,1,0,1,0,0,0,0,0,3,greenje02
|
||||
65,Rui Hachimura,PF,26,LAL,5,5,182,28,57,.491,15,31,.484,13,26,.500,.623,3,3,1.000,4,19,23,5,3,3,7,12,74,hachiru01
|
||||
66,Tyrese Haliburton,PG,24,IND,9,9,305,53,118,.449,16,55,.291,37,63,.587,.517,22,28,.786,3,46,49,85,6,8,17,13,144,halibty01
|
||||
67,Tim Hardaway Jr.,SG,32,DET,6,6,188,24,71,.338,16,52,.308,8,19,.421,.451,8,10,.800,2,15,17,7,2,0,9,10,72,hardati02
|
||||
68,James Harden,PG,35,LAC,7,7,276,44,101,.436,16,44,.364,28,57,.491,.515,27,33,.818,4,34,38,64,9,7,21,16,131,hardeja01
|
||||
69,Gary Harris,SG,30,ORL,5,0,83,3,8,.375,1,6,.167,2,2,1.000,.438,0,0,,1,4,5,3,3,1,0,7,7,harriga01
|
||||
70,Tobias Harris,PF,32,DET,6,6,233,34,71,.479,10,23,.435,24,48,.500,.549,16,16,1.000,8,38,46,3,6,7,6,16,94,harrito02
|
||||
71,Josh Hart,SG,29,NYK,10,10,375,44,90,.489,12,31,.387,32,59,.542,.556,24,32,.750,24,60,84,49,12,9,19,33,124,hartjo01
|
||||
72,Isaiah Hartenstein,C,26,OKC,8,8,209,36,65,.554,0,0,,36,65,.554,.554,8,12,.667,28,48,76,28,8,5,12,25,80,harteis01
|
||||
73,Sam Hauser,PF,27,BOS,6,0,78,6,13,.462,4,11,.364,2,2,1.000,.615,0,0,,0,8,8,2,1,1,3,7,16,hausesa01
|
||||
74,Jaxson Hayes,C,24,LAL,4,4,31,3,8,.375,0,0,,3,8,.375,.375,1,2,.500,5,3,8,1,0,1,1,8,7,hayesja02
|
||||
75,Tyler Herro,SG,25,MIA,4,4,144,27,65,.415,9,29,.310,18,36,.500,.485,8,10,.800,0,14,14,11,2,0,9,12,71,herroty01
|
||||
76,Buddy Hield,SG,32,GSW,11,8,298,50,116,.431,33,73,.452,17,43,.395,.573,9,10,.900,16,22,38,20,12,5,9,19,142,hieldbu01
|
||||
77,Haywood Highsmith,SF,28,MIA,4,0,84,11,19,.579,7,15,.467,4,4,1.000,.763,0,0,,4,9,13,4,3,2,4,11,29,highsha01
|
||||
78,Aaron Holiday,PG,28,HOU,3,0,27,4,10,.400,2,5,.400,2,5,.400,.500,2,4,.500,1,1,2,3,0,0,1,3,12,holidaa01
|
||||
79,Jrue Holiday,PG,34,BOS,6,6,202,23,44,.523,7,21,.333,16,23,.696,.602,5,6,.833,9,13,22,26,6,1,13,18,58,holidjr01
|
||||
80,Ron Holland,SF,19,DET,5,0,34,0,5,.000,0,3,.000,0,2,.000,.000,9,10,.900,3,3,6,0,0,1,6,5,9,hollaro01
|
||||
81,Chet Holmgren,C,22,OKC,8,8,239,41,98,.418,14,41,.341,27,57,.474,.490,31,37,.838,14,63,77,7,7,20,10,16,127,holmgch01
|
||||
82,Al Horford,C,38,BOS,9,7,297,25,58,.431,10,28,.357,15,30,.500,.517,6,7,.857,16,43,59,18,7,13,5,23,66,horfoal01
|
||||
83,Caleb Houstan,SF,22,ORL,5,0,47,2,14,.143,2,10,.200,0,4,.000,.214,0,0,,2,2,4,1,0,1,2,3,6,houstca01
|
||||
84,Jett Howard,SF,21,ORL,1,0,4,2,2,1.000,2,2,1.000,0,0,,1.500,0,0,,0,0,0,0,0,0,0,1,6,howarje01
|
||||
85,Jay Huff,C,26,MEM,2,0,18,2,4,.500,0,1,.000,2,3,.667,.500,4,4,1.000,1,2,3,1,0,3,1,1,8,huffja01
|
||||
86,Ariel Hukporti,C,22,NYK,1,0,2,1,1,1.000,0,0,,1,1,1.000,1.000,0,0,,0,2,2,0,0,0,0,0,2,hukpoar01
|
||||
87,De'Andre Hunter,SF,27,CLE,7,0,155,22,51,.431,10,22,.455,12,29,.414,.529,22,25,.880,4,20,24,7,3,1,7,13,76,huntede01
|
||||
88,Jonathan Isaac,PF,27,ORL,5,0,69,7,12,.583,1,4,.250,6,8,.750,.625,3,5,.600,5,5,10,2,2,1,2,3,18,isaacjo01
|
||||
89,Andre Jackson Jr.,SG,23,MIL,2,0,5,0,1,.000,0,1,.000,0,0,,.000,0,0,,0,0,0,0,0,0,0,0,0,jacksan01
|
||||
90,Jaren Jackson Jr.,C,25,MEM,4,4,137,22,58,.379,3,11,.273,19,47,.404,.405,17,20,.850,9,11,20,6,4,2,11,14,64,jacksja02
|
||||
91,Trayce Jackson-Davis,C,24,GSW,8,2,73,15,17,.882,0,0,,15,17,.882,.882,5,13,.385,7,12,19,2,2,2,1,15,35,jackstr02
|
||||
92,Bronny James,SG,20,LAL,2,0,4,0,2,.000,0,2,.000,0,0,,.000,0,0,,0,0,0,0,0,0,0,0,0,jamesbr02
|
||||
93,LeBron James,SF,40,LAL,5,5,204,43,88,.489,10,28,.357,33,60,.550,.545,31,40,.775,12,33,45,28,10,9,13,8,127,jamesle01
|
||||
94,Jaime Jaquez Jr.,SF,23,MIA,3,0,19,1,6,.167,0,2,.000,1,4,.250,.167,2,2,1.000,3,1,4,1,0,0,1,1,4,jaqueja01
|
||||
95,Ty Jerome,SG,27,CLE,8,1,180,34,87,.391,12,33,.364,22,54,.407,.460,17,20,.850,5,17,22,30,4,1,11,13,97,jeromty01
|
||||
96,Isaiah Joe,SG,25,OKC,8,0,105,18,38,.474,12,31,.387,6,7,.857,.632,3,4,.750,6,5,11,10,4,0,4,5,51,joeis01
|
||||
97,James Johnson,PF,37,IND,2,0,13,2,3,.667,0,1,.000,2,2,1.000,.667,1,2,.500,0,1,1,2,2,2,1,1,5,johnsja01
|
||||
98,Keshad Johnson,SF,23,MIA,2,0,8,1,1,1.000,0,0,,1,1,1.000,1.000,0,0,,1,0,1,0,0,0,1,1,2,johnske10
|
||||
99,Nikola Jokić,C,29,DEN,11,11,441,100,220,.455,20,59,.339,80,161,.497,.500,54,73,.740,21,119,140,92,24,11,47,37,274,jokicni01
|
||||
100,Derrick Jones Jr.,SF,27,LAC,7,1,129,21,48,.438,6,20,.300,15,28,.536,.500,3,8,.375,5,8,13,2,4,9,3,3,51,jonesde02
|
||||
101,Dillon Jones,SF,23,OKC,2,0,16,2,3,.667,0,1,.000,2,2,1.000,.667,2,2,1.000,0,2,2,1,0,1,2,1,6,jonesdi01
|
||||
102,DeAndre Jordan,C,36,DEN,7,0,36,3,3,1.000,0,0,,3,3,1.000,1.000,0,4,.000,1,8,9,2,0,1,2,9,6,jordade01
|
||||
103,Cory Joseph,PG,33,ORL,5,5,124,10,24,.417,5,16,.313,5,8,.625,.521,0,0,,1,8,9,15,5,2,2,10,25,josepco01
|
||||
104,Nikola Jović,PF,21,MIA,4,0,75,13,35,.371,6,24,.250,7,11,.636,.457,6,6,1.000,4,12,16,6,3,1,5,2,38,jovicni01
|
||||
105,Luke Kennard,SG,28,MEM,4,0,80,8,18,.444,2,9,.222,6,9,.667,.500,0,0,,2,12,14,8,4,1,6,3,18,kennalu01
|
||||
106,Braxton Key,SF,27,GSW,5,0,23,1,8,.125,0,1,.000,1,7,.143,.125,0,0,,5,4,9,1,2,2,3,4,2,keybr01
|
||||
107,Maxi Kleber,PF,33,LAL,1,0,5,0,1,.000,0,1,.000,0,0,,.000,2,2,1.000,0,0,0,0,0,0,1,1,2,klebima01
|
||||
108,Dalton Knecht,SF,23,LAL,2,0,4,2,5,.400,1,4,.250,1,1,1.000,.500,0,0,,2,1,3,0,0,0,0,0,5,knechda01
|
||||
109,Kevin Knox,SF,25,GSW,5,0,38,8,20,.400,1,6,.167,7,14,.500,.425,4,5,.800,3,4,7,4,0,1,2,2,21,knoxke01
|
||||
110,John Konchar,SG,28,MEM,4,0,69,3,9,.333,1,6,.167,2,3,.667,.389,4,4,1.000,3,10,13,6,2,2,2,8,11,konchjo01
|
||||
111,Luke Kornet,C,29,BOS,9,0,134,14,21,.667,0,0,,14,21,.667,.667,7,7,1.000,12,17,29,3,5,5,3,14,35,kornelu01
|
||||
112,Jonathan Kuminga,PF,22,GSW,7,1,155,34,70,.486,7,16,.438,27,54,.500,.536,21,28,.750,6,11,17,10,2,4,11,11,96,kuminjo01
|
||||
113,Kyle Kuzma,PF,29,MIL,5,4,102,12,35,.343,2,10,.200,10,25,.400,.371,3,6,.500,3,8,11,4,0,1,3,12,29,kuzmaky01
|
||||
114,Jock Landale,C,29,HOU,1,0,5,1,2,.500,0,0,,1,2,.500,.500,0,0,,0,0,0,0,0,0,0,0,2,landajo01
|
||||
115,Pelle Larsson,SG,23,MIA,4,0,52,8,15,.533,3,8,.375,5,7,.714,.633,1,3,.333,2,7,9,4,1,0,2,6,20,larsspe01
|
||||
116,Alex Len,C,31,LAL,2,0,4,0,1,.000,0,0,,0,1,.000,.000,0,0,,3,1,4,0,0,0,0,0,0,lenal01
|
||||
117,Kawhi Leonard,SF,33,LAC,7,7,265,66,123,.537,15,37,.405,51,86,.593,.598,28,36,.778,11,42,53,33,8,5,15,12,175,leonaka01
|
||||
118,Damian Lillard,PG,34,MIL,3,3,75,6,27,.222,3,16,.188,3,11,.273,.278,6,7,.857,1,7,8,14,2,2,3,8,21,lillada01
|
||||
119,Chris Livingston,SF,21,MIL,2,0,5,0,1,.000,0,1,.000,0,0,,.000,0,0,,0,1,1,0,0,0,0,0,0,livinch01
|
||||
120,Kevon Looney,C,28,GSW,11,0,114,10,23,.435,0,0,,10,23,.435,.435,6,8,.750,16,24,40,3,5,4,2,27,26,looneke01
|
||||
121,Brook Lopez,C,36,MIL,5,4,74,8,22,.364,4,15,.267,4,7,.571,.455,5,5,1.000,3,5,8,4,1,5,4,11,25,lopezbr01
|
||||
122,Bennedict Mathurin,SF,22,IND,8,0,144,28,59,.475,9,31,.290,19,28,.679,.551,29,33,.879,4,16,20,5,5,1,10,19,94,mathube01
|
||||
123,Miles McBride,PG,24,NYK,10,0,171,18,48,.375,12,32,.375,6,16,.375,.500,2,4,.500,0,10,10,8,4,0,5,10,50,mcbrimi01
|
||||
124,T.J. McConnell,PG,32,IND,9,0,156,36,68,.529,3,6,.500,33,62,.532,.551,11,12,.917,5,24,29,42,4,0,12,8,86,mccontj01
|
||||
125,Jaden McDaniels,PF,24,MIN,9,9,319,56,98,.571,10,26,.385,46,72,.639,.622,18,21,.857,17,40,57,11,10,8,8,30,140,mcdanja02
|
||||
126,Sam Merrill,SG,28,CLE,8,3,159,15,40,.375,14,39,.359,1,1,1.000,.550,2,3,.667,7,13,20,14,4,2,2,18,46,merrisa01
|
||||
127,Jordan Miller,SF,25,LAC,3,0,13,3,7,.429,0,1,.000,3,6,.500,.429,1,2,.500,0,2,2,4,3,0,0,0,7,millejo02
|
||||
128,Leonard Miller,SF,21,MIN,2,0,5,1,2,.500,0,0,,1,2,.500,.500,0,0,,1,1,2,0,0,0,0,0,2,millele01
|
||||
129,Patty Mills,PG,36,LAC,1,0,4,1,2,.500,1,1,1.000,0,1,.000,.750,0,0,,0,0,0,0,0,0,1,1,3,millspa02
|
||||
130,Shake Milton,SG,28,LAL,2,0,4,0,1,.000,0,0,,0,1,.000,.000,0,0,,0,0,0,0,0,0,0,1,0,miltosh01
|
||||
131,Josh Minott,SF,22,MIN,2,0,6,1,3,.333,0,2,.000,1,1,1.000,.333,0,0,,0,0,0,1,0,0,0,0,2,minotjo01
|
||||
132,Ajay Mitchell,SG,22,OKC,3,0,30,6,13,.462,3,6,.500,3,7,.429,.577,1,2,.500,0,2,2,2,1,0,1,4,16,mitchaj01
|
||||
133,Davion Mitchell,PG,26,MIA,4,3,142,25,41,.610,7,14,.500,18,27,.667,.695,3,7,.429,2,7,9,25,3,1,8,11,60,mitchda01
|
||||
134,Donovan Mitchell,SG,28,CLE,8,8,251,78,169,.462,24,71,.338,54,98,.551,.533,51,68,.750,9,24,33,34,13,2,15,16,231,mitchdo01
|
||||
135,Evan Mobley,PF,23,CLE,7,7,220,43,75,.573,13,29,.448,30,46,.652,.660,14,16,.875,16,38,54,12,9,6,11,10,113,mobleev01
|
||||
136,Moses Moody,SG,22,GSW,11,2,181,25,74,.338,13,42,.310,12,32,.375,.426,10,12,.833,8,17,25,12,4,3,3,13,73,moodymo01
|
||||
137,Ja Morant,PG,25,MEM,3,3,82,22,53,.415,4,16,.250,18,37,.486,.453,7,11,.636,1,5,6,15,2,2,6,3,55,moranja01
|
||||
138,Jamal Murray,PG,27,DEN,11,11,459,86,188,.457,28,69,.406,58,119,.487,.532,39,45,.867,6,49,55,61,14,8,33,23,239,murraja01
|
||||
139,Andrew Nembhard,SG,25,IND,9,9,291,48,98,.490,19,38,.500,29,60,.483,.587,13,15,.867,5,26,31,54,13,2,15,20,128,nembhan01
|
||||
140,Aaron Nesmith,SF,25,IND,9,9,259,48,88,.545,26,49,.531,22,39,.564,.693,11,12,.917,14,38,52,14,5,8,7,35,133,nesmiaa01
|
||||
141,Zeke Nnaji,PF,24,DEN,5,0,25,1,6,.167,1,4,.250,0,2,.000,.250,4,7,.571,3,2,5,2,1,2,2,5,7,nnajize01
|
||||
142,Chuma Okeke,PF,26,CLE,3,0,13,1,4,.250,1,4,.250,0,0,,.375,0,0,,0,0,0,1,1,0,0,0,3,okekech01
|
||||
143,Isaac Okoro,SG,24,CLE,8,0,111,14,28,.500,6,16,.375,8,12,.667,.607,5,8,.625,4,7,11,5,5,1,3,12,39,okorois01
|
||||
144,Cameron Payne,PG,30,NYK,10,0,74,10,26,.385,3,13,.231,7,13,.538,.442,1,3,.333,0,5,5,6,4,0,5,15,24,payneca01
|
||||
145,Gary Payton II,SG,32,GSW,10,1,174,21,47,.447,9,23,.391,12,24,.500,.543,0,0,,10,14,24,16,9,0,6,21,51,paytoga02
|
||||
146,Jalen Pickett,SG,25,DEN,7,0,48,3,10,.300,1,4,.250,2,6,.333,.350,0,0,,0,5,5,3,0,1,6,3,7,pickeja02
|
||||
147,Scotty Pippen Jr.,PG,24,MEM,4,4,129,22,58,.379,10,28,.357,12,30,.400,.466,19,19,1.000,4,18,22,14,4,1,14,19,73,pippesc02
|
||||
148,Brandin Podziemski,SG,21,GSW,11,10,346,37,113,.327,18,61,.295,19,52,.365,.407,15,19,.789,14,40,54,33,13,2,16,15,107,podzibr01
|
||||
149,Craig Porter Jr.,PG,24,CLE,6,0,35,6,12,.500,0,3,.000,6,9,.667,.500,0,0,,3,3,6,9,3,2,2,2,12,portecr01
|
||||
150,Kevin Porter Jr.,SG,24,MIL,5,1,151,19,48,.396,7,15,.467,12,33,.364,.469,11,13,.846,3,15,18,27,4,0,9,12,56,porteke02
|
||||
151,Michael Porter Jr.,SF,26,DEN,11,11,354,39,96,.406,22,56,.393,17,40,.425,.521,10,14,.714,11,55,66,6,5,5,11,19,110,portemi01
|
||||
152,Bobby Portis,PF,29,MIL,5,1,158,30,68,.441,10,28,.357,20,40,.500,.515,0,1,.000,8,33,41,7,2,2,6,8,70,portibo01
|
||||
153,Kristaps Porziņģis,C,29,BOS,9,6,207,24,72,.333,3,22,.136,21,50,.420,.354,29,41,.707,20,25,45,8,10,7,8,23,80,porzikr01
|
||||
154,Quinten Post,PF,24,GSW,11,2,136,15,44,.341,9,28,.321,6,16,.375,.443,3,4,.750,6,19,25,12,3,3,4,19,42,postqu01
|
||||
155,Norman Powell,SG,31,LAC,7,7,238,42,89,.472,14,40,.350,28,49,.571,.551,14,18,.778,1,16,17,17,8,2,12,15,112,powelno01
|
||||
156,Taurean Prince,SF,30,MIL,5,2,61,2,10,.200,2,9,.222,0,1,.000,.300,0,0,,0,5,5,8,2,1,5,3,6,princta02
|
||||
157,Payton Pritchard,PG,27,BOS,9,0,235,34,72,.472,21,49,.429,13,23,.565,.618,14,17,.824,6,12,18,10,5,0,9,17,103,pritcpa01
|
||||
158,Neemias Queta,C,25,BOS,2,0,6,2,2,1.000,0,0,,2,2,1.000,1.000,0,0,,0,0,0,1,0,0,0,0,4,quetane01
|
||||
159,Julius Randle,PF,30,MIN,9,9,334,73,151,.483,17,49,.347,56,102,.549,.540,47,53,.887,14,37,51,54,8,2,26,31,210,randlju01
|
||||
160,Austin Reaves,SG,26,LAL,5,5,196,30,73,.411,15,47,.319,15,26,.577,.514,6,7,.857,4,23,27,18,1,3,14,18,81,reaveau01
|
||||
161,Paul Reed,C,25,DET,5,0,53,5,8,.625,0,0,,5,8,.625,.625,4,6,.667,7,8,15,1,5,3,5,8,14,reedpa01
|
||||
162,Naz Reid,C,25,MIN,9,0,232,37,70,.529,21,43,.488,16,27,.593,.679,7,11,.636,6,26,32,16,8,7,16,26,102,reidna01
|
||||
163,Duncan Robinson,SF,30,MIA,4,0,59,5,14,.357,4,12,.333,1,2,.500,.500,3,4,.750,0,4,4,1,0,0,6,6,17,robindu01
|
||||
164,Mitchell Robinson,C,26,NYK,10,0,186,15,29,.517,0,0,,15,29,.517,.517,11,38,.289,37,28,65,4,8,4,8,20,41,robinmi01
|
||||
165,Ryan Rollins,PG,22,MIL,3,1,30,4,13,.308,2,7,.286,2,6,.333,.385,0,0,,1,1,2,4,1,0,0,4,10,rolliry01
|
||||
166,Gui Santos,PF,22,GSW,9,0,56,8,13,.615,4,7,.571,4,6,.667,.769,4,6,.667,0,7,7,8,3,0,6,9,24,santogu01
|
||||
167,Baylor Scheierman,SG,24,BOS,2,0,6,1,3,.333,1,1,1.000,0,2,.000,.500,0,0,,0,2,2,0,0,0,0,1,3,scheiba01
|
||||
168,Dennis Schröder,PG,31,DET,6,0,164,26,53,.491,10,21,.476,16,32,.500,.585,13,16,.813,4,10,14,22,7,1,7,12,75,schrode01
|
||||
169,Alperen Şengün,C,22,HOU,7,7,256,59,131,.450,3,8,.375,56,123,.455,.462,25,40,.625,21,62,83,37,13,3,15,26,146,sengual01
|
||||
170,Landry Shamet,SG,27,NYK,5,0,22,1,3,.333,0,1,.000,1,2,.500,.333,0,0,,0,0,0,0,0,0,2,0,2,shamela01
|
||||
171,Terrence Shannon Jr.,SG,24,MIN,5,0,18,2,6,.333,0,0,,2,6,.333,.333,0,0,,1,4,5,2,2,0,0,2,4,shannte01
|
||||
172,Ben Sheppard,SG,23,IND,7,0,92,9,21,.429,5,16,.313,4,5,.800,.548,2,2,1.000,3,9,12,1,0,0,3,10,25,sheppbe01
|
||||
173,Reed Sheppard,PG,20,HOU,3,0,10,0,2,.000,0,2,.000,0,0,,.000,0,0,,0,1,1,1,2,1,1,1,0,sheppre01
|
||||
174,Pascal Siakam,PF,30,IND,9,9,281,68,119,.571,13,29,.448,55,90,.611,.626,18,27,.667,6,48,54,26,8,2,12,29,167,siakapa01
|
||||
175,Ben Simmons,PG,28,LAC,5,0,42,2,6,.333,0,0,,2,6,.333,.333,0,0,,3,4,7,4,1,4,2,11,4,simmobe01
|
||||
176,Jericho Sims,C,26,MIL,5,0,58,6,6,1.000,0,0,,6,6,1.000,1.000,2,3,.667,11,9,20,1,0,1,5,5,14,simsje01
|
||||
177,Jabari Smith Jr.,PF,21,HOU,7,0,143,17,34,.500,10,22,.455,7,12,.583,.647,8,10,.800,7,20,27,4,1,5,10,6,52,smithja05
|
||||
178,Pat Spencer,PG,28,GSW,7,0,57,15,23,.652,1,2,.500,14,21,.667,.674,3,3,1.000,4,6,10,5,3,0,4,8,34,spencpa01
|
||||
179,Lamar Stevens,PF,27,MEM,2,0,12,2,9,.222,0,3,.000,2,6,.333,.222,0,0,,0,4,4,1,0,0,1,1,4,stevela01
|
||||
180,Isaiah Stewart,C,23,DET,1,0,19,1,2,.500,0,0,,1,2,.500,.500,0,0,,1,4,5,1,0,2,0,5,2,stewais01
|
||||
181,Julian Strawther,SG,22,DEN,6,0,41,5,12,.417,2,4,.500,3,8,.375,.500,2,3,.667,2,0,2,1,0,1,2,7,14,strawju01
|
||||
182,Max Strus,SF,28,CLE,8,8,227,37,80,.463,26,61,.426,11,19,.579,.625,5,6,.833,13,31,44,33,6,2,7,19,105,strusma01
|
||||
183,Jayson Tatum,PF,26,BOS,8,8,322,74,175,.423,29,78,.372,45,97,.464,.506,48,54,.889,9,83,92,43,17,6,26,21,225,tatumja01
|
||||
184,Amen Thompson,SF,22,HOU,7,7,231,42,85,.494,1,4,.250,41,81,.506,.500,25,36,.694,19,29,48,23,12,6,12,18,110,thompam01
|
||||
185,Ausar Thompson,SF,22,DET,6,6,135,24,42,.571,0,2,.000,24,40,.600,.571,21,36,.583,8,23,31,6,7,5,11,25,69,thompau01
|
||||
186,Tristan Thompson,C,33,CLE,3,0,29,3,6,.500,0,0,,3,6,.500,.500,1,3,.333,2,13,15,1,1,2,2,2,7,thomptr01
|
||||
187,Obi Toppin,PF,26,IND,9,0,148,31,59,.525,9,25,.360,22,34,.647,.602,9,14,.643,4,18,22,15,6,2,7,16,80,toppiob01
|
||||
188,Karl-Anthony Towns,C,29,NYK,10,10,365,75,152,.493,13,35,.371,62,117,.530,.536,34,37,.919,22,94,116,12,8,10,19,45,197,townska01
|
||||
189,Gary Trent Jr.,SG,26,MIL,5,3,171,32,62,.516,22,44,.500,10,18,.556,.694,8,10,.800,1,10,11,6,13,0,3,9,94,trentga02
|
||||
190,Myles Turner,C,28,IND,9,9,276,52,101,.515,17,38,.447,35,63,.556,.599,34,42,.810,11,42,53,13,7,21,11,23,155,turnemy01
|
||||
191,Hunter Tyson,PF,24,DEN,4,0,21,3,7,.429,0,3,.000,3,4,.750,.429,4,4,1.000,2,3,5,1,1,0,1,1,10,tysonhu01
|
||||
192,Jaylon Tyson,SG,22,CLE,4,0,31,7,15,.467,5,9,.556,2,6,.333,.633,5,6,.833,3,4,7,7,2,1,2,4,24,tysonja01
|
||||
193,Jarred Vanderbilt,PF,25,LAL,5,0,60,2,6,.333,0,1,.000,2,5,.400,.333,3,4,.750,4,15,19,5,3,1,3,9,7,vandeja01
|
||||
194,Fred VanVleet,PG,30,HOU,7,7,280,40,93,.430,27,62,.435,13,31,.419,.575,24,24,1.000,3,26,29,31,7,2,13,16,131,vanvlfr01
|
||||
195,Gabe Vincent,PG,28,LAL,5,0,99,5,14,.357,4,13,.308,1,1,1.000,.500,0,0,,0,5,5,5,1,2,1,8,14,vincega01
|
||||
196,Dean Wade,PF,28,CLE,8,1,123,4,15,.267,3,13,.231,1,2,.500,.367,0,0,,8,24,32,6,3,1,2,6,11,wadede01
|
||||
197,Franz Wagner,SF,23,ORL,5,5,195,51,115,.443,7,37,.189,44,78,.564,.474,20,26,.769,3,21,24,28,6,2,10,16,129,wagnefr01
|
||||
198,Jarace Walker,PF,21,IND,9,0,96,10,29,.345,6,16,.375,4,13,.308,.448,2,4,.500,0,19,19,8,1,1,5,8,28,walkeja02
|
||||
199,Cason Wallace,SG,21,OKC,8,0,158,16,35,.457,7,17,.412,9,18,.500,.557,1,2,.500,8,14,22,18,9,2,5,21,40,wallaca01
|
||||
200,Jordan Walsh,PF,20,BOS,3,0,7,0,0,,0,0,,0,0,,,0,0,,0,0,0,1,0,0,0,0,0,walshjo01
|
||||
201,Kel'el Ware,C,20,MIA,4,4,73,8,18,.444,3,11,.273,5,7,.714,.528,0,0,,4,15,19,4,1,2,2,3,19,wareke01
|
||||
202,Peyton Watson,SF,22,DEN,11,0,150,21,40,.525,6,11,.545,15,29,.517,.600,4,10,.400,8,18,26,2,8,7,4,15,52,watsope01
|
||||
203,Russell Westbrook,PG,36,DEN,10,0,254,46,111,.414,18,53,.340,28,58,.483,.495,24,34,.706,14,22,36,29,11,0,20,35,134,westbru01
|
||||
204,Derrick White,SG,30,BOS,9,9,345,56,120,.467,31,83,.373,25,37,.676,.596,22,25,.880,14,38,52,35,6,9,10,17,165,whitede01
|
||||
205,Cam Whitmore,SF,20,HOU,3,0,5,0,2,.000,0,1,.000,0,1,.000,.000,0,0,,0,1,1,0,0,0,0,0,0,whitmca01
|
||||
206,Aaron Wiggins,SG,26,OKC,8,0,112,27,54,.500,11,27,.407,16,27,.593,.602,6,7,.857,8,15,23,4,4,1,6,7,71,wiggiaa01
|
||||
207,Andrew Wiggins,SF,29,MIA,4,4,122,16,43,.372,7,20,.350,9,23,.391,.453,7,10,.700,4,9,13,9,1,5,11,6,46,wiggian01
|
||||
208,Jalen Williams,SG,23,OKC,8,8,277,63,137,.460,11,45,.244,52,92,.565,.500,31,41,.756,9,29,38,42,11,7,12,13,168,willija06
|
||||
209,Jaylin Williams,PF,22,OKC,8,0,71,8,14,.571,5,10,.500,3,4,.750,.750,2,5,.400,1,10,11,6,3,2,5,16,23,willija07
|
||||
210,Jeenathan Williams,SG,25,HOU,3,0,5,0,1,.000,0,1,.000,0,0,,.000,0,0,,0,0,0,0,0,0,1,1,0,willije02
|
||||
211,Kenrich Williams,PF,30,OKC,3,0,29,4,14,.286,0,6,.000,4,8,.500,.286,2,2,1.000,2,10,12,2,4,0,2,2,10,willike04
|
||||
212,Vince Williams Jr.,SG,24,MEM,3,0,38,4,7,.571,4,7,.571,0,0,,.857,2,2,1.000,1,6,7,4,2,1,3,3,14,willivi01
|
||||
213,Delon Wright,PG,32,NYK,1,0,3,0,0,,0,0,,0,0,,,0,0,,0,0,0,0,0,0,0,0,0,wrighde01
|
||||
214,Ivica Zubac,C,27,LAC,7,7,256,54,82,.659,0,0,,54,82,.659,.659,14,26,.538,27,44,71,16,5,7,11,19,122,zubaciv01
|
||||
|
Reference in New Issue
Block a user