package main
import (
"encoding/csv"
"fmt"
"goquery"
"log"
"net/http"
"os"
"strconv"
"strings"
)
var baseURL string = "https://kr.indeed.com/jobs?q=python&limit=50"
type extractedJob struct {
id string
title string
location string
salary string
summary string
}
func main() {
var jobs []extractedJob
totalPages := getPages()
for i := 0; i < totalPages; i++ {
extractedJobs := getPage(i)
jobs = append(jobs, extractedJobs...)
//...을 불여야 두개의 배열을 합치고, 안 붙이면 배열안에 배열이 하나 더 생긴다.
}
writeJobs(jobs)
fmt.Println("Done, extracted")
}
func writeJobs(jobs []extractedJob) {
file, err := os.Create("jobs.csv")
checkErr(err)
w := csv.NewWriter(file)
defer w.Flush()
headers := []string{"ID", "Title", "Location", "Salary", "Summary"}
wErr := w.Write(headers)
checkErr(wErr)
for _, job := range jobs {
jobSlice := []string{"https://kr.indeed.com/viewjob?jk=" + job.id, job.title, job.location, job.salary, job.summary}
jwErr := w.Write(jobSlice)
checkErr(jwErr)
}
}
func getPage(page int) []extractedJob {
var jobs []extractedJob
pageURL := baseURL + "&start=" + strconv.Itoa(page*50)
fmt.Println("Requesting", pageURL)
res, err := http.Get(pageURL)
defer res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
checkErr(err)
searchCards := doc.Find(".jobsearch-SerpJobCard")
searchCards.Each(func(i int, card *goquery.Selection) {
job := extractJob(card)
jobs = append(jobs, job)
})
return jobs
}
func getPages() int {
pages := 0
res, err := http.Get(baseURL)
checkErr(err)
checkCode(res)
defer res.Body.Close()
doc, err := goquery.NewDocumentFromReader(res.Body)
checkErr(err)
doc.Find(".pagination").Each(func(i int, s *goquery.Selection) {
pages = s.Find("a").Length()
})
return pages
}
func extractJob(card *goquery.Selection) extractedJob {
id, _ := card.Attr("data-jk")
title := cleanString(card.Find(".title>a").Text())
location := cleanString(card.Find(".sjcl").Text())
salary := cleanString(card.Find(".salaryText").Text())
summary := cleanString(card.Find(".summary").Text())
return extractedJob{
id: id,
title: title,
location: location,
salary: salary,
summary: summary}
}
//string을 받아서 공백을 제거한 후 fields 함수로 배열로 리턴받고 그 배열들을 Join으로 하나로 만든다 " "를 이용해서.
func cleanString(s string) string {
return strings.Join(strings.Fields(strings.TrimSpace(s)), " ")
}
// 에러체크 부분
func checkErr(err error) {
if err != nil {
log.Fatalln(err)
}
}
func checkCode(res *http.Response) {
if res.StatusCode != 200 {
log.Fatalln("Request failed with Status:", res.StatusCode)
}
}
#고루틴을 사용하지 않고, 일반 프로그램처럼 구동하는 상태입니다.
다음에는 이 코드를 사용하여 고루틴을 이용, 고를 제대로 사용해 봅시다.
'GO' 카테고리의 다른 글
노마드와 함께하는 고 Study -5 Goroutine #3 (URL 체커에 도입) (0) | 2020.03.24 |
---|---|
노마드와 함께하는 고 Study -5 Goroutine #2 (0) | 2020.03.24 |
노마드와 함께하는 고 Study -5 Goroutine (0) | 2020.03.24 |
노마드와 함께하는 고 Study -4 URL 체커 (0) | 2020.03.23 |
노마드와 함께하는 고 Study -3 메소드 (0) | 2020.03.23 |