import requests as rq
from bs4 import BeautifulSoup as bs
url = 'https://bodyluv.kr/product/%EB%B0%94%EB%94%94%EB%9F%BD-%EB%94%A5%EC%8A%AC%EB%A6%BD-%EC%BF%A8-%EC%9D%B4%EB%B6%88-v2-%EC%95%88%ED%8B%B0%EB%B2%84%EA%B7%B8/437/category/1/display/2/#prdReview'
res = req.get(url)
res
#<Response [403]>
멜론과 마찬가지로 프로그래밍 언어로 접근하는 것을 제한했다.
header = {'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'}
header를 입력한다.
res = req.get(url,headers = header)
<Response [200]>
soup 사용
soup = bs(res.text,"lxml")
review = soup.select("div.review_list_v2__message.js-collapsed-review-content.js-translate-text")
#[]
결과값이 나오지 않는다. 이는 리뷰를 수집할 때 많이 발생하는 상황으로 여러 개의 페이지로 구성되어 있을 때 발생하는 문제다. 한 페이지 안에 원하는 값이 여러개의 페이지로 구성되어 있을 때 많은 자원이 소모된다. 따라서 개발자 도구에서 Crtl + F
를 누르면 'Find by string, selector, or Xpath창이 나온다.
iframe
검색
기존 페이지 안에 새로운 페이지를 삽입하는 태그로 기존페이지에서는 iframe안에 있는 값을 가져올 수 없다. iframe안에 있는 src 속성의 url을 접근해야 리뷰를 가져올 수 있다.
맨 앞페이지에 있는 5개의 리뷰만 수집해보자
재설정
url = 'https://review4.cre.ma/bodyluv.kr/products/reviews?product_code=437&iframe_id=crema-product-reviews-2&widget_style=&app=0&parent_url=https%3A%2F%2Fbodyluv.kr%2Fproduct%2F%25EB%25B0%2594%25EB%2594%2594%25EB%259F%25BD-%25EB%2594%25A5%25EC%258A%25AC%25EB%25A6%25BD-%25EC%25BF%25A8-%25EC%259D%25B4%25EB%25B6%2588-v2-%25EC%2595%2588%25ED%258B%25B0%25EB%25B2%2584%25EA%25B7%25B8%2F437%2Fcategory%2F1%2Fdisplay%2F2%2F%23prdReview&nonmember_token=&secure_device_token=V2799214d481add415a9429522453d8c9efe11789214afdf92e25055f4e2c5d9ffee87a1582dec8e7cc7a800a6021a6820&iframe=1'
res = rq.get(url)
soup = bs(res.text,"lxml")
review = soup.select("div.review_list_v2__message.js-collapsed-review-content.js-translate-text")
review
#[<div class="review_list_v2__message js-collapsed-review-content js-translate-text" style="max-height: 54px">
아이들 여름 이불을 바꾸려고 겅색중 알게되어 구입했는데 신랑이 탐을 내어 하나더 구입 했네요. 촉감도 양면으로 부트러운면콰 시윈한 냉감이 있어 좋네요. 여름 이불로 적극 추천입니다<br/><br/><br/>(2020-08-07 14:26:40 에 등록된 네이버 페이 구매평)....
리뷰만 설정
for i in review:
print(i.text)
공백이 있는 모습이다. 공백을 제거하고 인덱스를 넣어보자.
cnt = 1
for i in review:
print(cnt)
print(i.text.strip())
cnt +=1
1 ~ 9페이지 리뷰 수집
for page in range(1,10):
url = f'https://review4.cre.ma/bodyluv.kr/products/reviews?app=0&iframe=1&iframe_id=crema-product-reviews-2&page={page}&parent_url=https%3A%2F%2Fbodyluv.kr%2Fproduct%2F%25EB%25B0%2594%25EB%2594%2594%25EB%259F%25BD-%25EB%2594%25A5%25EC%258A%25AC%25EB%25A6%25BD-%25EC%25BF%25A8-%25EC%259D%25B4%25EB%25B6%2588-v2-%25EC%2595%2588%25ED%258B%25B0%25EB%25B2%2584%25EA%25B7%25B8%2F437%2Fcategory%2F1%2Fdisplay%2F2%2F%23prdReview&product_code=437&secure_device_token=V214ced108fe66bbc87b88a2a925ca9beeda117f60a37e7211921fcc84209f6e1d3009c5b80b547cceedd39764d9df1362&widget_env=100&widget_style='
print(url)
분리된 리뷰 페이지 첫 번째 페이지에서는 page정보가 안 나오는 경우가 있으니 분리하고 2페이지를 가서 pages를 찾아서 f, {page}
정리를 하자.
cnt = 1
for page in range(1,10):
url = f'https://review4.cre.ma/bodyluv.kr/products/reviews?app=0&iframe=1&iframe_id=crema-product-reviews-2&page={page}&parent_url=https%3A%2F%2Fbodyluv.kr%2Fproduct%2F%25EB%25B0%2594%25EB%2594%2594%25EB%259F%25BD-%25EB%2594%25A5%25EC%258A%25AC%25EB%25A6%25BD-%25EC%25BF%25A8-%25EC%259D%25B4%25EB%25B6%2588-v2-%25EC%2595%2588%25ED%258B%25B0%25EB%25B2%2584%25EA%25B7%25B8%2F437%2Fcategory%2F1%2Fdisplay%2F2%2F%23prdReview&product_code=437&secure_device_token=V214ced108fe66bbc87b88a2a925ca9beeda117f60a37e7211921fcc84209f6e1d3009c5b80b547cceedd39764d9df1362&widget_env=100&widget_style='
res = req.get(url)
soup = bs(res.text,"lxml")
review = soup.select("div.review_list_v2__message.js-collapsed-review-content.js-translate-text")
for j in review:
print(cnt)
print(j.text.strip())
cnt+=1
현재 바디럽 리뷰는 약 13000개다. 따라서 리뷰 페이지의 끝이 어딘 지 알 수 없다. 몇 페이지가 끝인지 모르는 상황에서 끝까지 가보자
<리뷰 수집 마무리>
try, exception문 사용
cnt = 1
try:
for page in range(1,1000):
url = f'https://review4.cre.ma/bodyluv.kr/products/reviews?app=0&iframe=1&iframe_id=crema-product-reviews-2&page={page}&parent_url=https%3A%2F%2Fbodyluv.kr%2Fproduct%2F%25EB%25B0%2594%25EB%2594%2594%25EB%259F%25BD-%25EB%2594%25A5%25EC%258A%25AC%25EB%25A6%25BD-%25EC%25BF%25A8-%25EC%259D%25B4%25EB%25B6%2588-v2-%25EC%2595%2588%25ED%258B%25B0%25EB%25B2%2584%25EA%25B7%25B8%2F437%2Fcategory%2F1%2Fdisplay%2F2%2F%23prdReview&product_code=437&secure_device_token=V214ced108fe66bbc87b88a2a925ca9beeda117f60a37e7211921fcc84209f6e1d3009c5b80b547cceedd39764d9df1362&widget_env=100&widget_style='
res = req.get(url)
soup = bs(res.text,"lxml")
review = soup.select("div.review_list_v2__message.js-collapsed-review-content.js-translate-text")
for j in review:
print(cnt)
print(j.text.strip())
cnt+=1
except:
print(page,"페이지에서 오류") #파이썬이어서 될 것이다. 자바에서는 안 된다. 안 되는게 개념적으로 맞다.