GO로 네이버 웹툰들의 평점 정보 가져오기
Naver Webtoon All rating crawler - 12/16/2019 ~ 12/19/2019
요일별 모든 웹툰들의 전체 화의 평점을 각 파일별로 나누어 크롤링해오는 프로그램
//스크래핑 대상 URL
const (
urlRoot = "https://comic.naver.com/webtoon/weekday.nhn"
urlSubRoot = "https://comic.naver.com"
)
📦패키지
"github.com/yhat/scrape"
"golang.org/x/net/html"
"golang.org/x/net/html/atom"
1일차 - 🌟네이버 웹툰 메인페이지서 모든 웹툰을 고루틴(쓰레드)를 통해 이동 후 페이지 평점 정보를 가지고 옴
2일차 - 🤹생각보다 너무 쉬워서 모든 웹툰의 최근 10화를 고루틴(쓰레드)를 통해 2차 이동 후 참여자 수도 가지고 옴
3일차 - 🐛자꾸 에러가 떠서 로그를 찍어보다가 19금 웹툰에서 막히는 것을 발견하고 고침
4일차 - 👨💻마지막으로 파일 입출력 처리에 관한 문제를 발견하고 오류 수정
모든 웹툰을 고루틴을 통해 이동하는 코드
//class가 title인(모든) 웹툰들 대상으로 원하는 URL파싱 후 반환하는 함수
func parseMainNodes(n *html.Node) bool {
if n.DataAtom == atom.A && n.Parent != nil {
return scrape.Attr(n, "class") == "title"
}
return false
}
urlList := scrape.FindAll(root, parseMainNodes)
//웹툰들 전부 긁어와서 for range로 순회
for _, link := range urlList {
// //대상 URL 출력
// fmt.Println("Mon Link : ", link, idx)
// //웹툰 제목
// fmt.Println(scrape.Attr(link, "title"))
fileName := scrape.Attr(link, "title")
fmt.Println("filename is : ", fileName)
//작업 대기열에 고루틴이 다 끝날때까지 기다릴 수 있게 추가
wg.Add(1) //Done 개수와 일치
//고루틴 시작 -> 작업 대기열 개수와 같아야 함.
go scrapContents(scrape.Attr(link, "href"), fileName)
}
고루틴이 있다면 동기화를 해야함
//동기화를 위한 작업 그룹 선언
var wg sync.WaitGroup
var mutex = &sync.Mutex{}
에러체크
//에러체크할 함수 선언하여 계속 사용해줌.
func errCheck(err error) {
if err != nil {
log.Fatal(err)
}
}
모든 웹툰의 최근 10화 웹툰을 고루틴을 통해 들어가는 코드
//<td class="title"> 최근 10화 웹툰 사이트들 태그 긁어오는 함수
func parseSubNodes(n *html.Node) bool {
// return n.Parent.DataAtom == atom.Td && scrape.Attr(n, "class") == "title"
if n.DataAtom == atom.A && n.Parent != nil {
return scrape.Attr(n.Parent, "class") == "title"
}
return false
}
recentList := scrape.FindAll(root, parseSubNodes)
//parseSubNodes 함수를 사용해서 원하는 노드 순회(평점 긁어오기)하면서 출력
//<td class="title"> 최근 10화 웹툰 사이트 태그
for _, link := range recentList {
//동기화
wg.Add(1)
mutex.Lock()
//해당 데이터 출력
go scrapRatingType(scrape.Attr(link, "href"), fn)
//파싱 데이터 -> 버퍼에 기록
// w.WriteString(scrape.Text(g) + "\r\n")
}
// w.Flush()
웹툰들의 평점과 참여자 수 정보를 가지고오는 코드
//<div class="..." id="topTotalStarPoint"> 가 있는 코드들 긁어오는 함수
func parseStarNodes(n *html.Node) bool {
return n.DataAtom == atom.Div && scrape.Attr(n, "id") == "topTotalStarPoint"
}
웹툰이름.txt 파일에 평점과 참여자 수를 자동으로 작성해주는 코드
//파일 스크림 생성(열기) -> 파일명, 옵션, 권한
file, err := os.OpenFile("/Users/jejeongmin/documents/go/src/NaverWebtoon_crawler/Scrape/"+fn+".txt", os.O_APPEND|os.O_CREATE|os.O_RDWR, os.FileMode(0777))
//에러체크
errCheck(err)
//메소드 종료 시 파일 닫아야 함
defer file.Close()
//쓰기 버퍼 선언
w := bufio.NewWriter(file)
for _, g := range scrape.FindAll(root, parseStarNodes) {
//URL 및 해당 데이터 출력
fmt.Println("result : ", scrape.Text(g))
//파싱 데이터 -> 버퍼에 기록
w.WriteString(scrape.Text(g) + "\r\n")
}
w.Flush()
😞아쉬웠던 점 + 고루틴(쓰레드)의 장점
19살이 안되서 19금웹툰의 정보를 갖고오지 못했다. 정보를 갖고오지 못하는 에러가 났음에도 다른 웹툰들의 정보를 모두 긁어올 수 있었던 건 고루틴(쓰레드)를 활용하였기 때문이다.
Leave a comment