Tutorial

[다나와리뷰] 크롤링하기(ajax 활용)

new_challenge 2019. 4. 21. 12:18
반응형

ajax을 활용한 크롤링 :

>> 페이지가 로딩 될때 이미 모든 정보가 넘어와있는경우에 사용이 가능하다

>> 굉장히 짧은 시간에 많은 정보를 크롤링 할 수 있다

 

다나와 페이지 확인

http://www.danawa.com/

 

스마트한 쇼핑검색, 다나와! : 가격비교 사이트

가격비교 사이트 - 온라인 쇼핑몰, 소셜커머스 전 상품 정보 가격비교 사이트, 비교하면 다나와

www.danawa.com

>> 아래 코드를 이해하기 위해서는 다나와 html에 대한 이해가 먼저 필요하다

>> 직접 들어가서 개발자 모드를 열고 확인해야함

 

 

Loading Library

#필요한 패키지 로딩
import time
import requests
from bs4 import BeautifulSoup

 

>> 크롤링 하는데 필요한 라이브러리를 먼저 로딩한다.

 

 

Product code crawling

#다나와 상품코드 크롤링

def getPcode(page):
    pCodeList = []
    for i in range(1,page+1):
        print(i,"페이지 입니다")
        headers = {
               "Referer" : "http://prod.danawa.com/",
               "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36"
                }

        params = {"page" : page, "listCategoryCode" : 206, "categoryCode" : 206, "physicsCate1":72, 
                  "physicsCate2":73,"physicsCate3":0, "physicsCate4":0, "viewMethod": "LIST", "sortMethod":"BoardCount",
                  "listCount":30, "group": 10, "depth": 2, "brandName":"","makerName":"","searchOptionName":"",
                  "sDiscountProductRate":0, "sInitialPriceDisplay":"N", 
                  "sPowerLinkKeyword":"세탁기", "oCurrentCategoryCode":"a:2:{i:1;i:144;i:2;i:206;}", 
                  "innerSearchKeyword":"",
                  "listPackageType":1, "categoryMappingCode":176, "priceUnit":0, "priceUnitValue":0, "priceUnitClass":"",
                  "cmRecommendSort":"N", "cmRecommendSortDefault":"N", "bundleImagePreview":"N", "nPackageLimit":5, 
                  "nPriceUnit":0, "isDpgZoneUICategory": "N", "sProductListApi":"search","priceRangeMinPrice":"","priceRangeMaxPrice":"",
                 "btnAllOptUse":"false"}

        res = requests.post("http://prod.danawa.com/list/ajax/getProductList.ajax.php", headers = headers, data=params)
        soup = BeautifulSoup(res.text, "html.parser")
        a = soup.findAll("a", attrs = {"name":"productName"})
        
        for i in range(len(a)):
            pCodeList.append(a[i]['href'][35:-12])
        
    return pCodeList

>> 다나와 각 상품의 리뷰를 크롤링 하는데 앞서 상품에 대한 코드를 크롤링한다

>> 상품에 대한 코드만 있으면 그 안에 있는 리뷰는 ajax으로 쉽게 가져올 수 있다.

>> 예를 들어 세탁기라고 검색한 뒤에 나오는 상품에 대해 먼저 크롤링을 한다고 가정한다.

     "sPowerLinkKeyword":"세탁기" 를 param으로 보낸다.

>> 위의 코드는 상품코드들이 담겨있는 ajax을 가져오기 위함이다.

 

 

<코드 설명>

1> 페이지 수를 지정해준다.

 - 다나와는 1page당 30개의 상품이 존재한다.

 

2> header와 params를 설정해준다.

 - 개발자모드에서 해당 ajax에 있는 header와 params의 정보를 모두 적어준다.

 - getProductList.ajax 안에 상품코드에 대해 나와있다.

 

getProductList.ajax

3> 해당 ajax을 request의 Post방식으로 읽는다

 - 이때 params와 header를 같이 보내준다.

 

4> BeautifulSoup의 html.parser를 통해 해당 파일을 읽는다.

- 그리고 findall을 활용하여 <a>태그 안의 name이 productName을 찾아서 a에 담는다

- a에는 상품코드가 담겨있는 html들이 담겨있다

- 그중에서 상품코드가 있는부분만 자른다 : ['href'][35:-12]

- 상품 코드들만 가져와 pCodeList에 담는다.

 

5> 실제 코드를 사용

 - 원하는 페이지 수를 파라미터로 보낸다

 - 한 페이지에 30개씩 총 90개의 상품코드를 가져온다.

 

 

 

 

 

 

 

Review crawling

#다나와 리뷰 크롤링

def danawaCraw(pcode, page):
    reviewlist = []
    for idx in range(1,page+1):
        headers = {"Referer" : "http://prod.danawa.com/info/?pcode=2703774&cate=102206", "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36"}
        params = {"t" : 0.3180507575057596, "prodCode" : pcode, "page" : idx, "limit":10, "score":0,"usefullScore":"Y", "_":1550639162598}

        res = requests.get("http://prod.danawa.com/info/dpg/ajax/companyProductReview.ajax.php?t=0.3180507575057596&prodCode=2703774&page=1&limit=10&score=0&sortType=&usefullScore=Y&_=1550639162598", headers = headers, params = params)
        soup = BeautifulSoup(res.text, "html.parser")
        divs = soup.find_all("div", attrs = {"style":"display:none;"})
        #print(idx,'페이지에서', len(divs),'개의 리뷰 크롤링완료')
        for i in range(len(divs)):
            reviewlist.append(" ".join(divs[i].text.split()))
        #print('리스트에 리뷰 넣기 완료')
    return reviewlist

 

 

Time Check

#걸리는 시간 측정
start_time = time.time() 

#리뷰가 담길 리스트 생성
TotalReview = []

#가져온 상품코드를 사용해서 해당 리뷰 크롤링하기
for p in getPcode(3): #괄호안에 원하는 상품페이지 수 입력 (1페이지당 상품 30개)
    TotalReview.append(danawaCraw(p,5)) # 괄호안 순자에 원하는 리뷰 페이지 수 입력

#최종으로 걸리는 시간 파악
print("--- %s seconds ---" %(time.time() - start_time))

 

 

Crawling result check

 

반응형