Files
2022-04-07 11:39:05 +10:00

113 lines
3.0 KiB
Go

package handlers
import (
"strings"
"time"
"strconv"
colly "github.com/gocolly/colly/v2"
"github.com/jinzhu/gorm"
"github.com/rs/zerolog/log"
"github.com/wahyd4/scraper/model"
"github.com/wahyd4/scraper/utils"
)
const (
bedsSelector = "span.css-1g2pbs1"
propertySelector = "ul.css-qflns9"
)
func ScrapHouses(city string, date time.Time, db *gorm.DB, e *colly.HTMLElement) {
suburb := e.ChildText("h3")
log.Info().Msgf("scraping houses in %s %s on %s", city, suburb, date)
e.ForEach(propertySelector, func(index int, element *colly.HTMLElement) {
house := model.House{
City: city,
}
house.Suburb = suburb
element.ForEach("li", func(housePropertyIndex int, element *colly.HTMLElement) {
switch housePropertyIndex {
case 0:
house.URL = element.ChildAttr("a", "href")
house.Address = getHouseAddress(index, element)
case 1:
house.HouseType = element.ChildText("span:first-child")
rawBedsString := element.ChildText(bedsSelector)
house.BedNumber = utils.ToBeds(rawBedsString)
case 2:
house.SoldStatus = element.ChildText("span:first-child")
// price
rawPriceString := element.ChildText("span.css-m75dnw")
price := utils.ToMoney(rawPriceString)
house.Price = price
if price == -1 {
house.PriceWithheld = true
}
default:
house.Agent = element.Text
}
})
house.ActionDate = date
if err := db.Create(&house).Error; err != nil {
log.Error().Msgf("can't save house to db %s with error %s", house.URL, err.Error())
return
}
log.Info().Msgf("saved a house %s with action date %v", house.Address, date)
})
}
func ScrapClearanceRate(city string, date time.Time, db *gorm.DB, e *colly.HTMLElement) {
result := model.AuctionResult{City: city, AuctionDate: date}
e.ForEach("tbody tr", func(index int, childrenElement *colly.HTMLElement) {
title := childrenElement.ChildText("th")
value := childrenElement.ChildText("td")
switch title {
case "Clearance rate*":
result.ClearanceRate = utils.PercentStringToFloat(value)
case "Total auction":
totalAuction, _ := strconv.Atoi(value)
result.TotalAuction = totalAuction
case "Confirmed results":
confirmedResult, _ := strconv.Atoi(value)
result.ConfirmedResult = confirmedResult
case "Sold":
sold, _ := strconv.Atoi(value)
result.Sold = sold
case "Withdrawn":
withdrawn, _ := strconv.Atoi(value)
result.Withdrawn = withdrawn
case "Passed in":
passedIn, _ := strconv.Atoi(value)
result.PassedIn = passedIn
case "Total sales":
result.TotalSales = utils.ToMoney(value)
case "Median":
result.MedianPrice = utils.ToMoney(value)
}
})
if err := db.Create(&result).Error; err != nil {
log.Error().Msgf("can't save clearance rate %s on %s to db with error %s", city, date, err.Error())
return
}
}
func getHouseAddress(houseIndex int, element *colly.HTMLElement) string {
fullContent := element.Text
if houseIndex == 0 {
// strip the css styles if index is 0
indexOfRightBracket := strings.LastIndex(fullContent, "}")
return fullContent[indexOfRightBracket+1:]
}
return fullContent
}