코린이의 개발 일지

[파이썬 웹크롤링] 파이썬으로 네이버 웹툰 목록 가져와서 별점순 정렬하기 (BeautifulSoup) 본문

프로젝트/콘솔 프로그램

[파이썬 웹크롤링] 파이썬으로 네이버 웹툰 목록 가져와서 별점순 정렬하기 (BeautifulSoup)

폴라민 2022. 1. 24. 13:57
반응형

안녕하세요 폴라민 입니다.

 

오늘은 저번 포스팅에 이어서 웹툰 웹크롤링 하기 2탄 입니다.

저번 포스팅에서 설명했던 부분은 그냥 넘어갈 예정이라 혹시 Beautifulsoup을 처음 다뤄 보시는 분들은 

아래 포스팅을 참고해주시면 감사하겠습니다.

 

 

- 완전 기본적인 크롤링하기

https://polarmin.tistory.com/32

 

- 네이버 웹툰 제목 크롤링하기

https://polarmin.tistory.com/33

 

 

자 그럼 시작하겠습니다. 

 

저번과는 다르게 이번에는 별점 정보를 가져와서 활용할 건데 보아 하니 전체 웹툰을 보여주는 페이지는 별점 정보가 없더군요...

 

Beautifulsoup은 셀레니움과 다르게 동적으로 크롤링을 할 수가 없어서 하는 수 없이 특정 요일 웹툰들만 나온 페이지에서 크롤링을 진행해 보겠습니다.

 

저는 금요일 웹툰이 제일 많길래 금요일 웹툰으로 했는데 다른 요일로 하셔도 상관 없습니다.

 

 

 

 

 

 

 

 

금요 웹툰을 클릭하면 이렇게 제목, 작가, 별점이 뜹니다. 이 세개의 정보를 가져와서 정렬해보겠습니다.

 

 

- 별점순으로 정렬하기

 

 

 

저번보다는 상당히 코드가 복잡하죠?

사실 가져오는 건 별거 없는데 정렬하느라 코드가 조금 추가 되었습니다. 

하나하나 살펴 봅시다.

 

 

import requests
from bs4 import BeautifulSoup

res=requests.get('https://comic.naver.com/webtoon/weekdayList?week=fri') # 웹페이지 가져오기.
soup=BeautifulSoup(res.content,'html.parser') #웹페이지 파싱하기.

day_data=soup.find('div',class_='view_type')
day=day_data.find('h3',class_='sub_tit')
print(day.get_text())

 

코드 앞부분은 뭐 이제 아시겠죠? 저번과 거의 비슷합니다.

웹페이지 가져오고, 파싱하고.

 

저는 먼저 금요 전체 웹툰. 이라는 텍스트를 가져와서 출력해 줬습니다.

아래 캡져본 태그를 보시면 

 

 

 

 

div 태그 class="view_type"에서 h3 태그에 있는 텍스트를 긁어왔습니다.

 

다음 코드 보겠습니다.

 

import requests
from bs4 import BeautifulSoup

res=requests.get('https://comic.naver.com/webtoon/weekdayList?week=fri') # 웹페이지 가져오기.
soup=BeautifulSoup(res.content,'html.parser') #웹페이지 파싱하기.

day_data=soup.find('div',class_='view_type')
day=day_data.find('h3',class_='sub_tit')
print(day.get_text())
data=soup.select('div.list_area.daily_img li')
dic={}
for item in data:
    title=item.select_one('dt a') 
    author=item.select_one('dd a')
    rate=item.select_one('div.rating_type strong')
    dic[float(rate.get_text())]=[title.get_text(),author.get_text()]

 

 

우선 제목은 긁어 왔으니 이제 웹툰 목록이 있는 부분을 긁어왔습니다.

 

여기서 어? 처음 보는 명령어인데?

당황하실 필요 없습니다. 그냥 앞에서 다뤄왔던 거랑 거의 같아요.

data=soup.select('div.list_area.daily_img li')

 

css selector를 이용해서 크롤링을 해왔습니다.

 

 

 

 

지금 이부분을 가져온 것인데, 보시면 div 태그에 class 이름이 "list_area daily_img"으로 상당히 복잡하죠?

 

data=soup.select('div.list_area.daily_img li')

 

 

더보기

이 select 함수는 사실 find_all과 기능이 같아요. 태그에 해당하는 모든 HTML 내용을 찾아 리스트 형태로 리턴해줍니다. 

따라서 편한 함수를 쓰시면 됩니다. 단지 이런 것도 있다하고 소개드리려고 가져왔습니다.

 

select 함수 문법은 다음과 같아요.

soup.select('header strong')

-  header 태그 안에 있는 strong 태그

-  태그 안에 있는 모든 태그 가능

 

이때 class 이름으로도 가져올 수 있는데 예를 들어 div 태그이고 class 이름이 "title"이다. 그러면 

soup.select('div.title')

 

이런식으로 쓰면 됩니다.

 

만약 class 이름에 공백이 있을 경우 . 으로 연결합니다. 예를 들어 div 태그에 class = "tit blog" 일 경우

soup.select('div.tit.blog')

이렇게 쓰면 됩니다. 

 

 

위에서 쓴 걸 다시 볼까요?

 

 

data=soup.select('div.list_area.daily_img li')

 

해석?해보면 div 태그에 class = "list_area daily_img" (공백에는 . 을 찍어줬죠) 그리고 div 태그 안에 있는 li태그를 가리킵니다.

 

 

 

 

요 부분입니다. select 메소드는 이 지정한 태그에 해당하는 모든 데이터를 다 가져온다고 했죠?

따라서 밑에 있는 모든 li들을 가져와서 리스트에 담아 리턴해줍니다.

 

모든 금요 웹툰의 제목, 저자, 별점 내용을 가져왔네요. 이제 데이터 처리만 해주면 됩니다.

 

 

dic={}
for item in data:
    title=item.select_one('dt a') # dt 태그 안에 a 태그
    author=item.select_one('dd a') # dd 태그 안에 a 태그
    rate=item.select_one('div.rating_type strong') # div 태그 class="rating_type" 안에 strong태그
    dic[float(rate.get_text())]=[title.get_text(),author.get_text()]

 

저는 후에 정렬을 해주기 위해 딕셔너리 자료구조를 사용했습니다. 

 

data 변수에 데이터가 리스트 형태로 들어가 있으니 for문으로 요소하나씩 꺼내서 제목, 저자, 별점 다 따로 저장해 줍니다.

 

 

 

이때 select_one은 find 메소드랑 같은 기능이고 문법은 select 메소드와 같습니다. 

 

대충 아시겠죠? 

 

이렇게 가져온 데이터를 별점(rate)를 key값으로 해서 딕셔너리에 넣어줬습니다.

 

 

모든 데이터를 담았으니 이제 딕셔너리 정렬을 해주겠습니다.

 

import requests
from bs4 import BeautifulSoup

res=requests.get('https://comic.naver.com/webtoon/weekdayList?week=fri') # 웹페이지 가져오기.
soup=BeautifulSoup(res.content,'html.parser') #웹페이지 파싱하기.

day_data=soup.find('div',class_='view_type')
day=day_data.find('h3',class_='sub_tit')
print(day.get_text())
data=soup.select('div.list_area.daily_img li')
dic={}
for item in data:
    title=item.select_one('dt a')
    author=item.select_one('dd a')
    rate=item.select_one('div.rating_type strong')
    dic[float(rate.get_text())]=[title.get_text(),author.get_text()]

sort_dic=sorted(dic.items(),reverse=True)
print("별점순")
for rate,others in sort_dic:
    if rate<9.9:
        break
    print("제목: {} 저자: {} 평점:{}".format(others[0],others[1],rate))

 

정렬은 사실 간단해요. sorted함수 사용해서 정렬해주면 key값 기준으로 알아서 정렬해줍니다.

 

이제 정렬한 값을 for문을 돌려 출력을 해줬습니다. 

평점 9.9 이상인 것들만 출력해 주면

 

 

이렇게 잘 출력이 됩니다.

 

 

근데 인기순으로 보고 싶은데 별점은 9.9이상인 것들만 보고 싶을 수 있잖아요?

 

그렇게도 한번 해봤습니다.

 

 

 

import requests
from bs4 import BeautifulSoup

res=requests.get('https://comic.naver.com/webtoon/weekdayList?week=fri') # 웹페이지 가져오기.
soup=BeautifulSoup(res.content,'html.parser') #웹페이지 파싱하기.

day_data=soup.find('div',class_='view_type')
day=day_data.find('h3',class_='sub_tit')
print(day.get_text())
data=soup.select('div.list_area.daily_img li')
dic={}
for item in data:
    title=item.select_one('dt a')
    author=item.select_one('dd a')
    rate=item.select_one('div.rating_type strong')
    dic[float(rate.get_text())]=[title.get_text(),author.get_text()]

sort_dic=sorted(dic.items(),reverse=True)
print("별점순")
for rate,others in sort_dic:
    if rate<9.9:
        break
    print("제목: {} 저자: {} 평점:{}".format(others[0],others[1],rate))
print("\n인기순, 평점 9.9 이상")
for rate,others in dic.items():
    if rate<9.9:
        continue
    print("제목: {} 저자: {} 평점: {}".format(others[0],others[1],rate))

 

 

코드는 사실 밑에 출력해줄 부분만 좀 추가해 준것 말고는 별다른 게 없어요ㅎㅎ

 

 

 

이렇게 출력이 잘 되는 것을 볼 수 있습니다.

 

그럼 이상으로 포스팅을 마치겠습니다. 모두들 즐코 하세요!!

반응형
Comments