[PROJECT]-신용카드 추천 서비스[데이터 수집]
데이터 수집
함수부
모듈 로딩
from selenium.webdriver.chrome.service import Service
from selenium import webdriver as wd
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
import re
import time
팝업 광고 제거
# 프로모션 광고 제거
def kill_annoying_ad() :
try :
popup = driver.find_element(By.CSS_SELECTOR, "body > div:nth-child(16) > div.q-dialog__inner.flex.no-pointer-events.q-dialog__inner--minimized.q-dialog__inner--standard.fixed-full.flex-center > div > button")
except NoSuchElementException :
pass
else :
popup.click()
print("\n# 짜증나는 광고 처치")
카드사별 페이지 번호 로드
# 카드사별 고유 페이지 번호 받아오기
def get_pagenum(start=1, end=10) :
# 매개변수로 몇번째 페이지부터 몇번째 페이지까지 받아올지 설정
kill_annoying_ad()
page_num_list = []
class_names = driver.find_elements(By.CSS_SELECTOR, "#q-app > section > div.team > section > article > ul > li")
for class_name in class_names :
page_num = class_name.get_attribute("class")
page_num = re.sub(r"[^0-9]", "", page_num)
if re.match(r"0.+", page_num) :
page_num = page_num[1:]
company_name = class_name.find_element(By.CSS_SELECTOR,"p.name_kr").text
page_num_list.append((page_num, company_name))
page_num_list = page_num_list[start-1:end]
print("\n# ", end="")
for idx, item in enumerate(page_num_list) :
if idx == len(page_num_list)-1 :
print(item[1], end="")
else :
print(item[1], ", ", end="")
print("의 페이지 번호를 가져옴")
kill_annoying_ad()
return page_num_list
카드 url 로드
# 카드사별 페이지 접속 후 카드 url 받아오기
def get_url(page_num_list, log_name="data_urls") :
# 최종 결과물이 담길 변수 생성
data_urls = []
for page_num in page_num_list :
driver.get("https://www.card-gorilla.com/team/detail/{}".format(page_num[0]))
print("\n# {} 페이지에 접속.".format(page_num[1]))
time.sleep(2)
kill_annoying_ad()
# 모든 카드 목록을 펼쳐놓기
card_list_element = driver.find_element(By.CSS_SELECTOR, "#q-app > section > div.team_detail > section > div > article.con_area > div > div.player_lst.results_lst > ul")
next_sibling = driver.execute_script("""
return arguments[0].nextElementSibling
""", card_list_element)
while next_sibling.is_displayed() :
kill_annoying_ad()
to_next = driver.find_element(By.CSS_SELECTOR, "#q-app > section > div.team_detail > section > div > article.con_area > div > div.player_lst.results_lst > a")
to_next.click()
time.sleep(0.3)
print("\n* 모든 카드 목록을 펼침")
# 카드 이름과 혜택 정보가 적힌 url을
# 최종 결과물이 담길 변수 data_url에 저장
card_list = driver.find_elements(By.CSS_SELECTOR, "#q-app > section > div.team_detail > section > div > article.con_area > div > div.player_lst.results_lst > ul > li")
for card in card_list :
interrupt_issue = card.find_elements(By.CSS_SELECTOR, "p.txt_stop")
if len(interrupt_issue) != 0 :
continue # 신규발급중단(interrupt_issue) 상태 카드의 url은 크롤링 안함
card_url = dict()
name = card.find_element(By.CSS_SELECTOR, "p.card_tit").text
url = card.find_element(By.CSS_SELECTOR, "a.b_view").get_attribute("href")
card_url["name"] = name
card_url["info_url"] = url
data_urls.append(card_url) # 카드명과 url을 크롤링
print("\n* 카드 url 모두 불러옴, 총 개수 :", len(data_urls))
time.sleep(1)
kill_annoying_ad()
# data_url을 json으로 저장
import json
with open(f"{log_name}.json", "w") as j :
json.dump(data_urls, j)
j.close()
print("\n* url 저장 완료")
return data_urls
카드 혜택 정보 추출
# 카드의 정보와 혜택 추출
def get_benefits(data_urls, th = 10, log_name="data_benefits") :
# 모든 카드의 모든 정보, 혜택이 들어갈 변수
data = []
i = 0
for item in data_urls :
if i == th : break
i += 1
# 각각 카드의 정보와 혜택이 적힌 url에 접근
driver.get(item["info_url"])
time.sleep(1)
kill_annoying_ad()
# 카드 정보 추출
card_info = {} # 카드 한개의 정보가 들어갈 변수
info_main = driver.find_element(By.CSS_SELECTOR, "#q-app > section > div.card_detail.fr-view > section > div > article.card_top > div > div > div.data_area")
# 카드 이름
card_info["name"] = info_main.find_element(By.CSS_SELECTOR, "div.tit > strong").text
# 카드사 이름
card_info["bank"] = info_main.find_element(By.CSS_SELECTOR, "div.tit > p").text
# 연회비 (국내전용 domestic)
try :
card_info["annual_dom"] = info_main.find_element(By.CSS_SELECTOR, "div.bnf2 > dl:nth-child(1) > dd.in_out > span:nth-child(1) > b").text
except NoSuchElementException :
card_info["annual_dom"] = None
# 연회비 (해외겸용 forigen)
try :
card_info["annual_for"] = info_main.find_element(By.CSS_SELECTOR, "div.bnf2 > dl:nth-child(1) > dd.in_out > span:nth-child(2) > b").text
except NoSuchElementException :
card_info["annual_for"] = None
# 전월실적
try :
last_usage = info_main.find_element(By.CSS_SELECTOR, "div.bnf2 > dl:nth-child(2) > dd > b").text
except NoSuchElementException :
card_info["last_usage"] = None
if last_usage == "없음" :
card_info["last_usage"] = "0"
else :
card_info["last_usage"] = last_usage + "0,000"
name = item["name"]
print(f"\n# {i}. {name} 카드의 이름, 카드사, 연회비, 전월실적을 불러옴.")
# 소비 카테고리별 혜택 추출
category_benefits = []
info_detail = driver.find_elements(By.CSS_SELECTOR, "#q-app > section > div.card_detail.fr-view > section > div > article.cmd_con.benefit > div.lst.inner.faq_area > dl")
for category in info_detail :
category_benefit = {}
# 소비 카테고리 이름
category_name = category.find_element(By.CSS_SELECTOR, "strong").text
category_benefit["name"] = category_name
# 혜택 내용 요약 - 나중에 텍스트 전처리 필요!
benefit_summary = category.find_element(By.CSS_SELECTOR, "i").text
category_benefit["summary"] = benefit_summary
# 혜택 내용 상세를 보기 위해 클릭
trigger = category.find_element(By.CSS_SELECTOR, "dt")
driver.execute_script("arguments[0].click();", trigger)
kill_annoying_ad()
if category_name == "선택형" :
category_benefit["detail"] = "개별확인요망" # 이건 도대체 어떻게 해야할지...
else :
benefit_detail = category.find_element(By.CSS_SELECTOR, "div.in_box").text
category_benefit["detail"] = benefit_detail
category_benefits.append(category_benefit)
print(f"{category_name} 카테고리의 카테고리명, 혜택 내용 요약, 상세 내용을 불러옴.")
time.sleep(0.4)
kill_annoying_ad()
card_info["category"] = category_benefits
# 카드 한개의 모든 혜택과 정보를 data 변수에 저장
name = item["name"]
data.append(card_info)
print(f"{name} 정보 추출 완료")
time.sleep(1.9)
kill_annoying_ad()
# 카드 혜택 정보 저장
import json
with open(f"{log_name}.json", "w") as j :
json.dump(data, j)
j.close()
print("\n카드 혜택 정보 저장 완료")
메인부
# 셀레니움 구동
service = Service(executable_path="./chromedriver/chromedriver.exe")
driver = wd.Chrome(service=service)
# 카드고릴라 카드사 목록 페이지 들어가기
driver.get("https://www.card-gorilla.com/team")
print("\n페이지 접속 성공 :", driver.title)
# 사이트 최초로 뜨는 광고 제거
time.sleep(4.5) # 광고가 4초쯤 뒤에 뜨니까 그때까지 기다리자
kill_annoying_ad()
# 카드사별 페이지 번호 받아오기
page_num_list = get_pagenum(start=1, end=1)
# 카드사별 페이지 접속 후
# 카드 혜택 정보가 적혀있는 url 받아오기
data_urls = get_url(page_num_list, log_name="data_urls")
# 카드의 정보와 혜택 추출하기
data_benefits = get_benefits(data_urls, th=2, log_name="data_benefits")
# 셀레니움 종료
driver.close()
결과
/result.png)
Leave a comment