Skip to content

Commit dfa76b5

Browse files
committed
거래소 아이템과 아이템 가격 수집 서비스 통합
- 완벽한 통합은 아닌, stat scraper 내 item scraping 작업을 task로 추가함. - 현재 item scraping은 가벼운 작업이지만 별도 서비스로 분리하긴 과한 상황이라고 판단하여, 적절히 1시간에 한 번 수집되는 구조로 추가함.
1 parent 6c8bd70 commit dfa76b5

2 files changed

Lines changed: 97 additions & 0 deletions

File tree

src/go/apps/market-item-stat-scraper/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ func main() {
3939

4040
scheduler := schedule.NewScheduler()
4141
scheduler.AddTask(schedule.NewTask("Market item stat scraping and converting", 10*time.Minute, combinedTask))
42+
// 아예 수집되지 않을 시 아이템의 bundle_count 등이 갱신되지 않는 문제가 있어서 수집 스케쥴에 포함시킴.
43+
// 단, 거의 변하지 않는 정보이기에 1시간 정도에 한 번만 수집되도록 설정함.
44+
// TODO: 또한 최초 seed data가 없을 시 단순히 수집에 실패하는 구조로 되어있기에 개선이 필요함.
45+
scheduler.AddTask(schedule.NewTask("Market item scraping and converting", 1*time.Hour, scraper.ScrapeItem))
4246

4347
err = scheduler.Run()
4448
if err != nil {

src/go/apps/market-item-stat-scraper/scraper/scraper.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,25 @@ func NewScraper(db loadb.DB) *Scraper {
2222
return &Scraper{db: db, rateLimiter: rate.NewLimiter(rate.Every(time.Second), 1)}
2323
}
2424

25+
func (s *Scraper) ScrapeItem() error {
26+
categories, err := s.getCategoriesToScrape()
27+
if err != nil {
28+
return fmt.Errorf("failed to get market item categories: %w", err)
29+
}
30+
31+
itemsToSave, err := s.getItemsToSave(categories)
32+
if err != nil {
33+
return fmt.Errorf("failed to get market items: %w", err)
34+
}
35+
36+
err = s.saveItems(itemsToSave)
37+
if err != nil {
38+
return fmt.Errorf("failed to save market items: %w", err)
39+
}
40+
41+
return nil
42+
}
43+
2544
func (s *Scraper) ScrapeStat() error {
2645
items, err := s.getItemsToScrape()
2746
if err != nil {
@@ -114,3 +133,77 @@ func (s *Scraper) getItemStatToCreate(category *loadb.MarketItemCategory, item l
114133

115134
return &stat, nil
116135
}
136+
137+
func (s *Scraper) getCategoriesToScrape() ([]loadb.MarketItemCategory, error) {
138+
categories, err := s.db.MarketItemCategory().FindItemScraperEnabledAll()
139+
if err != nil {
140+
return nil, err
141+
}
142+
143+
if len(categories) == 0 {
144+
return nil, fmt.Errorf("no market item categories found")
145+
}
146+
147+
return categories, nil
148+
}
149+
150+
func (s *Scraper) getItemsToSave(categories []loadb.MarketItemCategory) ([]loadb.MarketItem, error) {
151+
var itemsToUpsert []loadb.MarketItem
152+
seenItems := make(map[string]bool)
153+
154+
for _, category := range categories {
155+
pageNo := 1
156+
157+
for {
158+
resp, err := request.GetMarketItemList(&loaApi.GetMarketItemListParams{
159+
CategoryCode: category.Code,
160+
PageNo: pageNo,
161+
})
162+
if err != nil {
163+
return nil, fmt.Errorf("failed to get market items for category %d: %w", category.Code, err)
164+
}
165+
166+
itemCounts := len(resp.Items)
167+
168+
if itemCounts > 0 {
169+
for _, item := range resp.Items {
170+
uniqueKey := fmt.Sprintf("%s-%s", item.Name, item.Grade)
171+
172+
if seenItems[uniqueKey] {
173+
log.Printf("중복 아이템 스킵: 이름=%s, 등급=%s, ID=%d",
174+
item.Name, item.Grade, item.ID)
175+
continue
176+
}
177+
178+
seenItems[uniqueKey] = true
179+
itemsToUpsert = append(itemsToUpsert, loadb.MarketItem{
180+
BundleCount: item.BundleCount,
181+
Grade: item.Grade,
182+
MarketItemCategoryID: category.ID,
183+
Name: item.Name,
184+
ImageUrl: item.Icon,
185+
RefID: item.ID,
186+
})
187+
}
188+
}
189+
190+
if itemCounts < resp.PageSize {
191+
break
192+
}
193+
194+
pageNo++
195+
}
196+
}
197+
198+
if len(itemsToUpsert) == 0 {
199+
return nil, fmt.Errorf("no market items found")
200+
}
201+
202+
return itemsToUpsert, nil
203+
}
204+
205+
func (s *Scraper) saveItems(items []loadb.MarketItem) error {
206+
log.Println("Market items saved successfully")
207+
208+
return s.db.MarketItem().UpsertMany(items)
209+
}

0 commit comments

Comments
 (0)