바디럽 리뷰 수집 BeautifulSoup

Happy_JG·2023년 8월 25일
0

크롤링

목록 보기
3/8
post-custom-banner
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개다. 따라서 리뷰 페이지의 끝이 어딘 지 알 수 없다. 몇 페이지가 끝인지 모르는 상황에서 끝까지 가보자

    1. 1000페이지까지 이동한다.
    1. 중간에 페이지에 끝을 마주친다. 이상황에서 오류가 발생하게 된다.
      만약 페이지에 끝을 본다면 그 페이지에서 마무리하자

<리뷰 수집 마무리>
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,"페이지에서 오류") #파이썬이어서 될 것이다. 자바에서는 안 된다. 안 되는게 개념적으로 맞다.
profile
hello!
post-custom-banner

0개의 댓글