지난번에 크롤링을 하면서 영화 제목을 긁어와서 출력했는데, 이번에는 랭킹과 평점도 같이 표시하도록 해보려고함.

import requests
from bs4 import BeautifulSoup
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
# old_content > table > tbody > tr:nth-child(2)
# old_content > table > tbody > tr:nth-child(2) > td.title > div > a
# old_content > table > tbody > tr:nth-child(2) > td:nth-child(1) > img
# old_content > table > tbody > tr:nth-child(2) > td.point
movies = soup.select('#old_content > table > tbody > tr')
reviews = []
for movie in movies:
temp = []
img = movie.select_one('img')
if img is not None:
temp.append(img['alt'])
a = movie.select_one('td.title > div > a')
if a is not None:
temp.append(a.text)
point = movie.select_one('td.point')
if point is not None:
temp.append(point.text)
if temp:
reviews.append(temp)
for review in reviews:
print('랭킹-' + review[0] + '. 제목:[' + review[1] + '] , 평점-' + review[2])
우선 일단 완성된 코드다. 그럼 몇가지 새롭게 알게된 것을 정리해보겠다.
전역으로 'reviews'라는 배열을 만들어 놓았다. 여기에 [랭킹,영화제목,평점] 이 들어갈 것이다. [[랭킹,영화제목,평점],[랭킹,영화제목,평점],[랭킹,영화제목,평점], ... ] 이런 형식이다.
for문 안에 임시 배열인 temp 가 있다. 여기에 1.랭킹 2.영화제목 3.평점 순으로 값을 추가하려고 한다.
1.배열에 값넣기
파이썬에는 배열에 값을 넣는 방법이 'append','extend','insert' 가 있다고한다.
append는 array.append(x) 와같은 형태로 사용. 새로운 요소를 배열 끝에 객체로 추가한다.
예)
nums = [1,2,3]
nums.append(4) // [1,2,3,4]
nums.append([5,6]) // [1,2,3,4,[5,6]]
extend도 append와 비슷하다. 'array.extend(iterable)' 와같은 형태. 입력한 요소를 배열 맨 끝에 추가하는게 append와 같다. 다른점은 iterable 자료형만 올 수 있다는 것. iterable이 아니면 TypeError가 발생.
예)
nums = [1,2,3]
nums.extend([4,5]) // [1,2,3,4,5]
a = [6,7]
nums.extend(a) // [1,2,3,4,5,6,7] append였으면 [1,2,3,4,5,[6,7]]
insert는 array.insert(i,x) 형태로 사용한다. 배열의 원하는 위치에 추가할 수 있다. i(index) 에 x를 추가할 수 있다.
예)
nums = [1,2,3,4]
nums.insert(1,7) // [1,7,2,3,4]
이번 예제에서는 값을 하나씩 맨 끝에 입력하기에 append를 사용했다.
2. 배열이 빈 배열인지 확인하기
temp에 들어가는 값중에 빈 배열이 들어가서 문제가 생겼다. 빈 배열의 원인은 영화사이트의 '구분선' 때문이었다.


구분선에는 랭킹,영화제목,평점 을 긁어올게 없기때문에 빈 배열이 temp에 들어가는 것을 막아야했다. 그러기위해서는 temp가 빈 강정인지 확인할 필요가 있었는데 배열이 비어있는지 확인하는 방법을 확인해보자.
첫번째방법은 흔히 내가 생각하는 .length 와 같은 방법이다. 근데 이러한 것은 파이썬스러운 코드가 아니라 사용을 지양하라고...
예)
list1 = []
list2 = [1,2,3]
if len(list1) == 0:
print("list1 is empty")
if len(list2) != 0:
print("list2 is not empty")
두번째방법은 파이썬스러운 코드라고함.
예)
list1 = []
list2 = [1,2,3]
if not list1:
print("list1 is empty")
if list2:
print("list2 is not empty")
'if not list1:' 은 '배열이 비어있다면' 이고 'if list2:' 는 '배열이라면(값이있다면)' 정도로 이해해야겠다.
코드를 좀 더 간결하게 개선해서 다시 작성해보았다.
import requests
from bs4 import BeautifulSoup
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
movies = soup.select('#old_content > table > tbody > tr')
reviews = []
for movie in movies:
temp = []
a = movie.select_one('td.title > div > a')
if a is not None:
rank = movie.select_one('td:nth-child(1) > img')['alt']
title = a.text
point = movie.select_one('td.point').text
temp.append(rank)
temp.append(title)
temp.append(point)
reviews.append(temp)
for review in reviews:
print('랭킹-' + review[0] + '. 제목:[' + review[1] + '] , 평점-' + review[2])
| [웹개발 종합반 1주차] 회고록 (0) | 2022.02.11 |
|---|---|
| [파이썬] ajax, API 만들기 (0) | 2022.01.25 |
| [파이썬]Flask 시작 - 서버만들기 (0) | 2022.01.25 |
| [파이썬] 텍스트 공백지우기, 범위 출력 (0) | 2022.01.25 |
| [파이썬] 웹스크래핑(크롤링) (0) | 2022.01.22 |