Python - [크롤링 실습] selenium으로 번개장터 조회하기 4 (엑셀로 출력 및 데이터 조회하기)

컴퓨터/Python

728x90
반응형

서론

지난 포스트에서 Pandas에 데이터를 넣어보았습니다.

이제 Pandas를 통해서 정리된 데이터를 효율적으로 사용하는 방법에 대해서 알아봅시다.

본문에서는 Pandas의 몇 가지 기능을 알아보도록 할 것입니다.

우선, 취득한 데이터를 엑셀파일과 csv파일로 저장해보도록 하고,

두 번째로 검색 결과의 평균값, 최저값, 최고값을 구해보는 과정을 해보도록 합시다.

 

 

Python - [크롤링 실습] selenium으로 번개장터 조회하기 3 (Pandas로 정제)

서론 지난 실습에 이어서 번개장터에서 selenium을 통해 크롤링을 진행했습니다. 이 정보들을 그냥 출력을 해서 사용하는 것은 크롤러가 대신해서 정보를 구해와서 얻어오기는 하지만, 정보들을

blog-of-gon.tistory.com

 

엑셀 또는 csv파일로 저장하기

코딩이나 프로그래밍에 익숙하지 않더라도, 엑셀은 사용할 수 있으신 분들이 많을 것 같습니다.

따라서, Python을 통해 취득한 데이터를 손쉽게 엑셀이나 csv파일로 출력하는 방법을 알아봅시다.

Pandas를 이용하면 정말정말 손쉽게 다양한 형식의 파일로 데이터를 출력할 수 있습니다.

 

이외에도 Pandas에 IOtoos에서 다양한 형식으로 데이터를 출력 가능합니다. (자세히

 

 

to_excel()

pandas로 만들어진 데이터프레임 객체에서 해당 메서드를 호출하는 것으로 엑셀 파일로 저장할 수 있습니다.

몇 가지 예시를 들어 익혀보도록 합시다.

 

단! 해당 메서드를 사용하기 위해서는 openpyxl이 반듯이 설치되어 있어야 합니다.

  • 파일명만 지정했을 경우 (소스코드 위치와 동일)
#pandas를 이용해서 데이터 정리하기
Datas = {
    "제목" : Subject,
    "가격" : Price,
    "등록일시" : Date,
    "위치" : Location,
    "링크" : Link,
    "상태" : Status
}
DataTable = ps.DataFrame(Datas)

#소스코드가 위치한 곳에 파일이 저장된다.
DataTable.to_excel("Datas.xlxs")
  • 경로를 지정하는 경우
DataTable.to_excel("./data/Datas.xlsx")
  • 인덱스 값의 포함 여부 (예 : 미포함)
DataTable.to_excel("./data/Datas.xlsx",index=False)
  • 특정 시트 및 이름 지정
DataTable.to_excel("./data/Datas.xlsx",sheet_name="번개장터 크롤링 결과")

 

to_csv()

가장 대표적인 문자열을 저장하는 형식으로서 특정 구분자를 통해 저장하는 혁 식입니다.

to_excel과 유사합니다.

  • 파일명만 지정했을 경우 (소스코드 위치와 동일)
DataTable.to_csv("Datas.csv")
  • 구분자 변경하기 (기본 구분자는 쉼표[ , ]입니다.)
DataTable.to_csv("Datas.csv",sep =";")

 

최대, 최저, 평균값 구하기

Pandas에 들어있는 데이터 중 특정 열에 존재하는 값의 최고, 최저, 평균값을 구해보도록 합시다.

해당 예제에서는 가격란에 있는 값들이 될 것입니다.

 

이 또한 저장된 데이터 프레임에서 특정 메서드를 호출하면 간단하게 가능해집니다.

  • . max (최대)
  • . min (최저)
  • mean (평균)

특정 열에서만 값을 취하고 싶다면 []로 특정 열의 이름을 지정해 주어야 합니다.

DataTable["가격"].max()

 

이제 실제 예제 소스코드에 해당 내용을 적어보도록 합시다.

MinPrice = DataTable['가격'].min()
MaxPrice = DataTable['가격'].max()
AvgPrice = DataTable['가격'].mean()

print("검색 결과의 최저가 : ",MinPrice)
print("검색 결과의 최대가 : ",MaxPrice)
print("검색 결과의 평균가 : ",AvgPrice)

이 결과를 실행하면 정상적으로 동작할까요? 

 

정상적으로 동작하지 않습니다. 

이유는 데이터가 숫자가 아닌 문자의 형태로 저장되어 있기 때문입니다.

그럼 어떻게 해야 될까요? pandas에는 당연하게도 문자열을 손쉽게 숫자로 바꿀 수 있게 해주는 기능이 있습니다.

 

to_numeric - 문자를 숫자로

해당 메서드를 사용하면 손쉽게 숫자의 형태로 변경할 수 있습니다.

문자열 안에 숫자로 바꾸지 못하는 내용이 있다면 제거 또한 가능합니다.

이 내용을 이용해서 먼저 데이터의 문자열을 숫자로 바꾸어 주도록 하겠습니다.

#가격란의 문자열 데이터를 숫자로 변경하기
DataTable["가격"] = ps.to_numeric(DataTable["가격"].str.replace(",",""))

 

전체 소스코드 및 결과 보기

  • 소스코드 보기
더보기
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
import pandas as ps

#정보를 저장할 list 생성해두기
Subject = []
Price = []
Date = []
Location = []
Link = []
Status = []


#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
    if page == 2 :
        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 처리 (Pandas로 수정될 부분)
        try:
            Subject.append(infor[0])  #print("제목 : ", infor[0])
            Price.append(infor[1])  #print("가격 : ", infor[1])
            if infor[2] is None:
                infor[2] = "미 확인"
            Date.append(infor[2])#print("시간 : ", infor[2])
            Location.append(location)#print("위치 : ", Location)
            Link.append("https://m.bunjang.co.kr{}".format(aTag.attrs['href'])) #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 = "판매 중"
            Status.append(status)#print("상태 : ",status)
        except:
            pass
    page = page+1

#pandas를 이용해서 데이터 정리하기
Datas = {
    "제목" : Subject,
    "가격" : Price,
    "등록일시" : Date,
    "위치" : Location,
    "링크" : Link,
    "상태" : Status
}
DataTable = ps.DataFrame(Datas)

#가격란의 문자열 데이터를 숫자로 변경하기
DataTable["가격"] = ps.to_numeric(DataTable["가격"].str.replace(",",""))


#엑셀로 저장하기
DataTable.to_excel("Datas.xlsx")

MinPrice = DataTable['가격'].min()
MaxPrice = DataTable['가격'].max()
AvgPrice = DataTable['가격'].mean()

print("검색 결과의 최저가 : ",MinPrice)
print("검색 결과의 최대가 : ",MaxPrice)
print("검색 결과의 평균가 : ",AvgPrice)
#print(DataTable)

자 해당 소스코드를 실행시키면 번개장터에서 검색된 결과의 첫 번째 페이지에서 데이터를 취득하여 최저, 최대, 평균 가격을 알려주는 것을 확인했습니다.

 

하지만 상당히 부정확합니다. 카테고리적인 분류나, 광고들 미끼상품 등의 비정상적인 금액 등을 전혀 필터링하지 못하기 때문입니다. 다음 포스트에서는 이런 내용들을 추가하며 조금 더 다양하게 데이터를 분석할 수 있도록 해보겠습니다.

728x90
반응형

Commnet

G91개발일지

Gon91(지구일)

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

TODAY :

YESTER DAY :

TOTAL :