Python - [크롤링 실습] selenium으로 번개장터 조회하기 2 (페이지 순환)

컴퓨터/Python

728x90
반응형

서론

지난 포스트에서는 단순하게 번개장터에서 검색 후 데이터를 취득하는 과정을 가지고 왔습니다.

단순히 처음 검색해서 나온 결과의 페이지에서만 데이터를 취득했습니다.

본문에서는 많은 이제 각각의 검색 결과의 모든 데이터를 취득하는 과정을 추가해 보도록 하겠습니다.

 

 

Python - [크롤링 실습] selenium으로 번개장터 조회하기 1 (접속,검색,취득)

서론 본격적으로 Python에서 크롤링을 해보기 위해서 번개장터 웹 페이지를 다뤄보도록 합시다. 초기 준비단계에서의 소스코드는 다음과 같습니다. from selenium import webdriver from selenium.webdriver.comm..

blog-of-gon.tistory.com

 

Get요청을 통한 페이지 순환 구현하기

번개장터를 통해 페이지를 검색하면 URL 주소가 바뀌는 것을 확인할 수 있습니다.

즉, Get요청을 통해 웹페이지가 변경되는 말입니다.

 

이  부분을 응용해서 page 수를 넘기면서 Get요청을 하고 만약 콘텐츠가 존재하지 않는다면 검색을 종료하면 됩니다.

 

사실 Selenium을 이용해서 페이지를 구현하는 방법은 아니지만 더 효율적이라고 생각되기 때문에, 

해당 Get요청 규칙을 이용해서 구현해보도록 합시다.

 

지난 포스트에서의 소스코드를 수정해보면 조금 더 불편한 부분이 수정되면서 크롤링이 가능해졌습니다.

 

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.ui import WebDriverWait
from bs4 import BeautifulSoup

#Selenium 구동
browser = webdriver.Chrome()
browser.implicitly_wait(time_to_wait=10)
browser.get('https://m.bunjang.co.kr/')

#검색 입력
itemname = input("검색어 입력 : ")

#페이지 순환을 위한 준비 및 Get요청 쿼리
page = 1
url = "https://m.bunjang.co.kr/search/products?order=score&page={}&q={}".format(page,itemname)

#페이지 순환
while True:
    url = "https://m.bunjang.co.kr/search/products?order=score&page={}&q={}".format(page, itemname)
    browser.get(url)
    print("*************",page,"번 Page**********************")
    # wating
    WebDriverWait(browser, 10).until(expected_conditions.visibility_of_element_located((By.CLASS_NAME, "app")))
    # html parsing
    html = browser.page_source
    html_parser = BeautifulSoup(html, features="html.parser")
    list = html_parser.find_all(attrs={'alt': '상품 이미지'})
    if list.__len__() == 0 :
        break
    #print
    for item in list:
        aTag = item.parent.parent
        print("정보 : ", aTag.get_text(separator=';;;'))
        print("링크 : ", "https://m.bunjang.co.kr{}".format(aTag.attrs['href']))
        st = item.parent.parent.get_text(separator=';;;')
    page = page+1

 

정보 출력 부분 수정하기

음.. 크롤러가 동작을  하긴 하는데... 정보를 보는 정보 자체가 약간 지저분한 면이 많습니다.

 

우선은, 그냥 콘솔에 출력하는 구조자체를 조금 변화를 시켜보도록 합시다.

향후에 엑셀이나 DB또는 Pandas 등을 이용해서 데이터를 이용할 예정입니다.

그리고 예약완료, 또는 판매 완료에 대한 정보도 취득합시다. 

 

예약 완료 또는 판매 완료 정보 취득

위와 같은 문구가 표시되면서 판매 불가한 상품들이 존재합니다. 이 또한 필요한 정보가 될 수 있으므로 수집해보도록 합시다. 지난 포스트에서처럼 이미지 대체 택스트를 이용해서 값을 취득했습니다.

 

        #판매 가능 여부 확인
        status = aTag.find(attrs={'alt': '판매 불가 아이콘'})
        if status is not None:
            status = status.parent.get_text()
        else:
            status = "판매 중"
        print("상태 : ",status)

 

정보 부분 최적화

정보 부분 출력하는 부분도 ;;;로 구분만 해서 출력했었습니다. 

지저분하고 불필요한 정보들도 포함되어 있습니다. 따라서 약간 찾는 방식을 수정하고 깔끔하게 출력해보도록 하겠습니다.

 

#페이지당 모든 아이템 탐색
    for item in list:
        aTag = item.parent.parent
        for i,c  in enumerate(aTag.children,0):
            if i == 1 :
                infor = c.get_text(separator=';;;')
                infor = infor.split(sep=';;;')
            if i == 2 :
                Location = c.get_text()
#탐색중 혹시모를 error 처리
        try:
            print("제목 : ", infor[0])
            print("가격 : ", infor[1])
            if infor[2] is None:
                infor[2] = "미 확인"
            print("시간 : ", infor[2])
            print("위치 : ", Location)
            print("링크 : ", "https://m.bunjang.co.kr{}".format(aTag.attrs['href']))
            st = item.parent.parent.get_text(separator=';;;')

            #판매 가능 여부 확인
            status = aTag.find(attrs={'alt': '판매 불가 아이콘'})
            if status is not None:
                status = status.parent.get_text()
            else:
                status = "판매 중"
            print("상태 : ",status)
        except:
            print("error!!")
    page = page+1

 

전체 소스코드 및 결과

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.ui import WebDriverWait
from bs4 import BeautifulSoup

#Selenium 구동
browser = webdriver.Chrome()
browser.implicitly_wait(time_to_wait=10)
browser.get('https://m.bunjang.co.kr/')

#검색 입력
itemname = input("검색어 입력 : ")

#페이지 순환을 위한 준비 및 Get요청 쿼리
page = 1
url = "https://m.bunjang.co.kr/search/products?order=score&page={}&q={}".format(page,itemname)

#페이지 순환
while True:
    url = "https://m.bunjang.co.kr/search/products?order=score&page={}&q={}".format(page, itemname)
    browser.get(url)
    print("*************",page,"번 Page**********************")
    # wating
    WebDriverWait(browser, 10).until(expected_conditions.visibility_of_element_located((By.CLASS_NAME, "app")))
    # html parsing
    html = browser.page_source
    html_parser = BeautifulSoup(html, features="html.parser")
    list = html_parser.find_all(attrs={'alt': '상품 이미지'})

    if list.__len__() == 0 :
        break

#페이지당 모든 아이템 탐색
    for item in list:
        aTag = item.parent.parent
        for i,c  in enumerate(aTag.children,0):
            if i == 1 :
                infor = c.get_text(separator=';;;')
                infor = infor.split(sep=';;;')
            if i == 2 :
                Location = c.get_text()
#탐색중 혹시모를 error 처리
        try:
            print("제목 : ", infor[0])
            print("가격 : ", infor[1])
            if infor[2] is None:
                infor[2] = "미 확인"
            print("시간 : ", infor[2])
            print("위치 : ", Location)
            print("링크 : ", "https://m.bunjang.co.kr{}".format(aTag.attrs['href']))
            st = item.parent.parent.get_text(separator=';;;')

            #판매 가능 여부 확인
            status = aTag.find(attrs={'alt': '판매 불가 아이콘'})
            if status is not None:
                status = status.parent.get_text()
            else:
                status = "판매 중"
            print("상태 : ",status)
        except:
            print("error!!")
    page = page+1

구동을 해보면 계속해서 페이지를 순환하면서 결과들을 긁어오는 것을 확인할 수 있습니다.

 

하지만, 지금 긁어온 결과들을 효과적으로 사용하기에는 다소 어려운 부분이 많이 존재합니다.

 

다양한 라이브러러리나 DB와 연동하는 방법은 추후에 살펴보도록 하고 우선, 다음 포스트에서는 엑셀을 이용한 파일을 담는 방법을 다뤄보도록 합시다.

728x90
반응형

Commnet

G91개발일지

Gon91(지구일)

91년생 공학엔지니어의 개발일지

TODAY :

YESTER DAY :

TOTAL :