💻

1. KOTRA 해외시장 뉴스

 

1.1 사이트 소개

https://dream.kotra.or.kr/dream/index.do 는 해외경제 정보를 제공해주는 사이트입니다.
「해외경제정보드림」 자체 수집, 생산한 KOTRA 해외시장뉴스,국가정보를 비롯한 핵심정보를 Open API,파일, 링크 등 다양한 형태로 공공데이터 포털을 통해 개방하고 있습니다.
해당 사이트 내에서 상품DB 카테고리를 살펴볼 예정입니다.
상품DB에는 각 국가별 최근 이슈가 되고있는 상품들에 대한 시장 동향 정보들을 제공하고 있습니다.
각 국가별, 대륙별, 산업분류별로 검색을 할 수 있습니다.
각 동향 자료에는 간략한 정보를 알 수 있는 키워드와 2줄 요약이 존재합니다.

1.2 해당 사이트 크롤링 목적

해당 사이트에서 제공하는 상품 시장 동향 정보를 이용하여 국가별, 대륙별 이슈가 되는 상품 데이터를 수집하여 과거부터 현재까지의 동향을 요약 정리 할 수 있습니다.
수집한 데이터를 이용하여 시장 동향을 예측하여 마케팅 및 상품 수출에 이용할 수 있습니다.
상품 동향 데이터를 분석하여 변수에 따른 시장 동향의 상관관계를 파악할 수 있습니다.

1.3 크롤링 가능 여부 체크

크롤링을 시작하기 전에 해당 페이지가 크롤링이 가능한지 먼저 체크를 해보아야합니다.
크롤링이 가능여부를 확인하기 위해서는 /robots.txt 를 이용하면 됩니다.
주초창에 https://dream.kotra.or.kr/robots.txt 를 입력합니다.
해당 웹페이지에 아래와 같은 결과가 나오게 됩니다.
User-agent: * Allow: /
모든 크롤러에 대해 모든 페이지가 허용되어있다는 결과가 나오게 됩니다.

1.4 Kotra 사이트 구조 살펴보기

먼저, Chrome의 우측 상단 부분 점 3개 아이콘을 클릭하여 Chrome 맞춤설정 및 제어로 들어갑니다. 그럼 [도구 더보기]에서 [개발자 도구]로 들어가면 [Elements] 라고 하는 웹 페이지를 구성하고 있는 HTML 코드를 분석하고 수정할 수 있는 도구 패널이 존재합니다. 저희는 이 부분을 활용하여 필요한 부분을 가져오도록 하겠습니다.

1.4.1 첫 페이지 XPATH

  • 게시글 순서에 따라 숫자가 변경됨
# 첫번째 게시글의 XPATH //*[@id="tbody"]/tr[1]/td[2]/a # 제목 //*[@id="tbody"]/tr[1]/td[3] # 국가 //*[@id="tbody"]/tr[1]/td[4] # 무역관 //*[@id="tbody"]/tr[1]/td[5] # 게시일 # 열번째 게시글의 XPATH //*[@id="tbody"]/tr[10]/td[2]/a # 제목 //*[@id="tbody"]/tr[10]/td[3] # 국가 //*[@id="tbody"]/tr[10]/td[4] # 무역관 //*[@id="tbody"]/tr[10]/td[5] # 게시일

1.4.2 상세 페이지 XPATH

  • 상세페이지 들어가는 부분만 다르고 나머지는 제목, 국가, 게시일, 키워드, 요약, 목록 요소는 동일
# 첫번째 게시글의 XPATH //*[@id="tbody"]/tr[1]/td[2]/a # 상세 페이지 들어가기 //*[@id="pdfArea"]/dl/dt/div[1]/strong # 제목 //*[@id="pdfArea"]/dl/dt/div[2]/ul/li[2] # 국가 //*[@id="pdfArea"]/dl/dt/div[2]/ul/li[4] # 게시일 //*[@id="pdfArea"]/dl/dd/div[1] # 키워드 //*[@id="pdfArea"]/dl/dd/div[2] # 요약 //*[@id="contents"]/article/div[1]/div[2]/a/span # 상세 페이지 나오기(목록) # 열번째 게시글의 XPATH //*[@id="tbody"]/tr[10]/td[2]/a # 상세 페이지 들어가기 //*[@id="pdfArea"]/dl/dt/div[1]/strong # 제목 //*[@id="pdfArea"]/dl/dt/div[2]/ul/li[2] # 국가 //*[@id="pdfArea"]/dl/dt/div[2]/ul/li[4] # 게시일 //*[@id="pdfArea"]/dl/dd/div[1] # 키워드 //*[@id="pdfArea"]/dl/dd/div[2] # 요약 //*[@id="contents"]/article/div[1]/div[2]/a/span # 상세 페이지 나오기(목록)

1.4.3 다음 페이지 XPATH

  • 페이지 번호에 따라 숫자가 변경됨
  • 다음 5개 목록 페이지로 이동한 후에도 페이지 번호는 동일하게 반복됨
# 2번째 페이지의 XPATH //*[@id="contents"]/article/div[4]/div[2]/ul/li[2]/button # 5번째 페이지의 XPATH //*[@id="contents"]/article/div[4]/div[2]/ul/li[5]/button # 7번째 페이지의 XPATH //*[@id="contents"]/article/div[4]/div[2]/ul/li[2]/button # 10번째 페이지의 XPATH //*[@id="contents"]/article/div[4]/div[2]/ul/li[5]/button # 다음 5개 목록 페이지로 이동 //*[@id="contents"]/article/div[4]/div[2]/button[3]/span
 

1.5 Kotra 해외 시장 상품 동향 크롤링하기

 
우선 저희가 크롤링할 사이트로 들어가보도록 하겠습니다. 저희가 크롤링할 부분은 상품산업 카테고리의 상품DB 파트로, 하단의 사이트 주소로 들어가면 됩니다.
 

1.5.1 첫 페이지 크롤링하기

첫 페이지를 보면 게시일, 검색, 대륙, 국가, 무역관, 산업분류, HSCODE와 같이 검색조건을 설정할 수 있게 되어 있지만, 저희는 조건을 따로 설정하지 않고 기본 페이지에서 크롤링을 진행하도록 하겠습니다.
먼저, 저희는 1페이지에 게시되어 있는 10개의 게시글의 제목, 국가, 무역관, 게시일을 차례로 크롤링해보도록 하겠습니다.
  1. 필요한 라이브러리들을 불러와보도록 하겠습니다.
from selenium import webdriver import pandas as pd import time # 다운받은 크롬드라이버 파일 경로 주소 넣기 path = "/Users/jieunlee/Downloads/chromedriver_mac_arm64/chromedriver" # 크롬 드라이버 실행 및 driver라는 변수명으로 객체 생성 driver = webdriver.Chrome(path) # 상품DB url로 이동하기 driver.get("https://dream.kotra.or.kr/kotranews/cms/com/index.do?MENU_ID=430") # 페이지가 로딩될 때까지 0.5초간 기다리기 time.sleep(0.5)
  1. 차례대로 제목, 국가, 무역관, 게시일을 각각 담을 수 있는 빈 리스트를 생성하도록 하겠습니다.
# 제목 담을 빈 리스트 title_list = [] # 국가 담을 빈 리스트 country_list = [] # 무역관 담을 빈 리스트 trade_list = [] # 게시일 담을 빈 리스트 date_list = []
  1. 제목, 국가, 무역관, 게시일에 해당하는 XPATH를 복사하여 텍스트 부분만 크롤링을 해온 후 위에서 생성한 빈 리스트에 추가해주는 코드를 생성합니다.
# 첫 번째부터 열 번째까지 게시물 요소 크롤링하기 for i in range(1, 11): # 제목 title = driver.find_element("xpath", f"""//*[@id="tbody"]/tr[{i}]/td[2]/a""").text title_list.append(title) # 국가 country = driver.find_element("xpath", f"""//*[@id="tbody"]/tr[{i}]/td[3]""").text country_list.append(country) # 무역관 trade = driver.find_element("xpath", f"""//*[@id="tbody"]/tr[{i}]/td[4]""").text trade_list.append(trade) # 게시일 date = driver.find_element("xpath", f"""//*[@id="tbody"]/tr[{i}]/td[5]""").text date_list.append(date)
  1. 위에서 수집한 내용들을 데이터프레임의 형태로 변환하도록 하겠습니다.
# 각 리스트에 있는 요소를 list_sum = list(zip(title_list, country_list, trade_list, date_list)) # 데이터 프레임의 칼럼명 생성 col = ["제목", "국가", "무역관", "날짜"] # 데이터 프레임 생성 df = pd.DataFrame(list_sum, columns=col) # 데이터 프레임 확인 df
notion imagenotion image
  1. 최종 코드입니다.
from selenium import webdriver import pandas as pd import time # 다운받은 크롬드라이버 파일 경로 주소 넣기 path = "/Users/jieunlee/Downloads/chromedriver_mac_arm64/chromedriver" # 크롬 드라이버 실행 및 driver라는 변수명으로 객체 생성 driver = webdriver.Chrome(path) # 상품DB url로 이동하기 driver.get("https://dream.kotra.or.kr/kotranews/cms/com/index.do?MENU_ID=430") # 페이지가 로딩될 때까지 0.5초간 기다리기 time.sleep(0.5) # 제목 담을 빈 리스트 title_list = [] # 국가 담을 빈 리스트 country_list = [] # 무역관 담을 빈 리스트 trade_list = [] # 게시일 담을 빈 리스트 date_list = [] # 첫 번째부터 열 번째까지 게시물 요소 크롤링하기 for i in range(1, 11): # 제목 title = driver.find_element("xpath", f"""//*[@id="tbody"]/tr[{i}]/td[2]/a""").text title_list.append(title) # 국가 country = driver.find_element("xpath", f"""//*[@id="tbody"]/tr[{i}]/td[3]""").text country_list.append(country) # 무역관 trade = driver.find_element("xpath", f"""//*[@id="tbody"]/tr[{i}]/td[4]""").text trade_list.append(trade) # 게시일 date = driver.find_element("xpath", f"""//*[@id="tbody"]/tr[{i}]/td[5]""").text date_list.append(date) # 각 리스트에 있는 요소를 list_sum = list(zip(title_list, country_list, trade_list, date_list)) # 데이터 프레임의 칼럼명 생성 col = ["제목", "국가", "무역관", "날짜"] # 데이터 프레임 생성 df = pd.DataFrame(list_sum, columns=col) # 데이터 프레임 확인 df
 

1.5.2 상세 페이지 크롤링하기

현재 제목이 “중국 냉장고 시장 동향”, “태국 집적회로 시장 동향” 과 같이 제목만으로는 쉽게 내용을 파악할 수 없습니다. 따라서 상세 페이지 안으로 들어가 크롤링 해보도록 하겠습니다.
  1. 필요한 라이브러리들을 불러와보도록 하겠습니다.
from selenium import webdriver import pandas as pd import time # 다운받은 크롬드라이버 파일 경로 주소 넣기 path = "/Users/jieunlee/Downloads/chromedriver_mac_arm64/chromedriver" # 크롬 드라이버 실행 및 driver라는 변수명으로 객체 생성 driver = webdriver.Chrome(path) # 상품DB url로 이동하기 driver.get("https://dream.kotra.or.kr/kotranews/cms/com/index.do?MENU_ID=430") # 페이지가 로딩될 때까지 0.5초간 기다리기 time.sleep(0.5)
  1. 이번에는 제목, 국가, 게시일, 키워드, 요약을 각각 담을 수 있는 빈 리스트를 생성하도록 하겠습니다.
# 제목 담을 빈 리스트 title_list = [] # 국가 담을 빈 리스트 country_list = [] # 게시일 담을 빈 리스트 date_list = [] # 키워드 담을 빈 리스트 keyword_list = [] # 요약 담을 빈 리스트 summary_list = []
  1. 이후 자동으로 상세 페이지로 들어가서 필요한 부분을 크롤링한 후 상세 페이지를 빠져나와 다시 목록으로 돌아갈 수 있도록 하는 코드를 생성하도록 하겠습니다. click()을 활용하여 클릭 동작을 실행할 수 있습니다.
  • 키워드 부분에서 ‘Keyword’, ‘#’(해시태그)와 같은 불필요한 부분을 제거하고, 앞 뒤 공백을 제거하는 코드를 넣어 깔끔하게 키워드만 가져오도록 하였습니다.
# 첫 번째부터 열 번째까지 게시물 요소 크롤링하기 for title_num in range(1, 11): time.sleep(0.5) # 상세 페이지 들어가기 driver.find_element("xpath", f"""//*[@id="tbody"]/tr[{title_num}]/td[2]/a""").click() # 제목 title = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dt/div[1]/strong""").text title_list.append(title) # 국가 country = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dt/div[2]/ul/li[2]""").text country_list.append(country) # 게시일 date = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dt/div[2]/ul/li[4]""").text date_list.append(date) # 키워드 keyword = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dd/div[1]""").text # 전처리 : Keyword 및 해시태그 제거 keyword = keyword.replace("Keyword", "").replace("#", "").strip() keyword_list.append(keyword) # 요약 summary = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dd/div[2]""").text summary_list.append(summary) # 상세 페이지 나오기 driver.find_element("xpath", """//*[@id="contents"]/article/div[1]/div[2]/a/span""").click()
  1. 위에서 수집한 내용들을 데이터프레임의 형태로 변환하도록 하겠습니다.
# 각 리스트에 있는 요소를 list_sum = list(zip(title_list, country_list, date_list, keyword_list, summary_list)) # 데이터 프레임의 칼럼명 생성 col = ["제목", "국가", "날짜", "키워드", "요약"] # 데이터 프레임 생성 df = pd.DataFrame(list_sum, columns=col) # 데이터 프레임 확인 df
notion imagenotion image
  1. 최종 코드 입니다.
from selenium import webdriver import pandas as pd import time # 다운받은 크롬드라이버 파일 경로 주소 넣기 path = "/Users/jieunlee/Downloads/chromedriver_mac_arm64/chromedriver" # 크롬 드라이버 실행 및 driver라는 변수명으로 객체 생성 driver = webdriver.Chrome(path) # 상품DB url로 이동하기 driver.get("https://dream.kotra.or.kr/kotranews/cms/com/index.do?MENU_ID=430") # 페이지가 로딩될 때까지 0.5초간 기다리기 time.sleep(0.5) # 제목 담을 빈 리스트 title_list = [] # 국가 담을 빈 리스트 country_list = [] # 게시일 담을 빈 리스트 date_list = [] # 키워드 담을 빈 리스트 keyword_list = [] # 요약 담을 빈 리스트 summary_list = [] # 첫 번째부터 열 번째까지 게시물 요소 크롤링하기 for title_num in range(1, 11): time.sleep(0.5) # 상세 페이지 들어가기 driver.find_element("xpath", f"""//*[@id="tbody"]/tr[{title_num}]/td[2]/a""").click() # 제목 title = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dt/div[1]/strong""").text title_list.append(title) # 국가 country = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dt/div[2]/ul/li[2]""").text country_list.append(country) # 게시일 date = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dt/div[2]/ul/li[4]""").text date_list.append(date) # 키워드 keyword = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dd/div[1]""").text # 전처리 : Keyword 및 해시태그 제거 keyword = keyword.replace("Keyword", "").replace("#", "").strip() keyword_list.append(keyword) # 요약 summary = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dd/div[2]""").text summary_list.append(summary) # 상세 페이지 나오기 driver.find_element("xpath", """//*[@id="contents"]/article/div[1]/div[2]/a/span""").click() # 각 리스트에 있는 요소를 list_sum = list(zip(title_list, country_list, date_list, keyword_list, summary_list)) # 데이터 프레임의 칼럼명 생성 col = ["제목", "국가", "날짜", "키워드", "요약"] # 데이터 프레임 생성 df = pd.DataFrame(list_sum, columns=col) # 데이터 프레임 확인 df
 

1.5.3 여러 페이지 크롤링하기

이제는 단일 페이지가 아닌 여러 페이지로부터 크롤링을 해오도록 하겠습니다. 1번째 페이지부터 10번째 페이지까지 크롤링을 해보도록 하겠습니다.
  1. 페이지 구조를 보면, 2번째 페이지부터 5번째 페이지까지는 하단에 페이지 숫자를 클릭하여 페이지를 이동하고, 6번째 페이지로 넘어가려면 ‘>’ 1개의 화살표 표시를 클릭해야 합니다.
이러한 규칙을 코드로 생성한다면 다음과 같이 작성할 수 있습니다.
  • 현재 페이지가 1번째 페이지일 경우 2번째 페이지로, 2번째 페이지일 경우 3번째 페이지로, 4번째 페이지일 경우 5번째 페이지로 넘어가기
  • 현재 페이지가 5번째 페이지일 경우 다음 5개 목록 페이지로 넘어가기
# 페이지 번호가 5의 배수가 아닐 경우 if (page_num % 5) != 0: # 현재 페이지 번호보다 1개 다음 페이지로 넘어가기 driver.find_element("xpath", f"""//*[@id="contents"]/article/div[4]/div[2]/ul/li[{page_num % 5 + 1}]/button""").click() # 페이지 번호가 5의 배수일 경우 else: # 다음 5개 목록 페이지로 넘어가기 driver.find_element("xpath", f"""//*[@id="contents"]/article/div[4]/div[2]/button[3]/span""").click()
  1. 위의 코드를 앞선 최종 코드에 적용시켜보도록 하겠습니다. 페이지 이동한 후 동일하게 상세 페이지로 들어가서 필요한 요소를 크롤링하는 것을 반복하는 코드를 작성하겠습니다.
from selenium import webdriver import pandas as pd import time # 다운받은 크롬드라이버 파일 경로 주소 넣기 path = "/Users/jieunlee/Downloads/chromedriver_mac_arm64/chromedriver" # 크롬 드라이버 실행 및 driver라는 변수명으로 객체 생성 driver = webdriver.Chrome(path) # 상품DB url로 이동하기 driver.get("https://dream.kotra.or.kr/kotranews/cms/com/index.do?MENU_ID=430") # 페이지가 로딩될 때까지 0.5초간 기다리기 time.sleep(0.5) # 제목 담을 빈 리스트 title_list = [] # 국가 담을 빈 리스트 country_list = [] # 게시일 담을 빈 리스트 date_list = [] # 키워드 담을 빈 리스트 keyword_list = [] # 요약 담을 빈 리스트 summary_list = [] for page_num in range(1, 11): time.sleep(0.5) for title_num in range(1, 11): time.sleep(0.5) # 상세 페이지 들어가기 driver.find_element("xpath", f"""//*[@id="tbody"]/tr[{title_num}]/td[2]/a""").click() # title title = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dt/div[1]/strong""").text title_list.append(title) # country country = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dt/div[2]/ul/li[2]""").text country_list.append(country) # date date = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dt/div[2]/ul/li[4]""").text date_list.append(date) # keyword keyword = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dd/div[1]""").text # 전처리 : Keyword 및 해시태그 제거 keyword = keyword.replace("Keyword", "").replace("#", "").strip() keyword_list.append(keyword) # summary summary = driver.find_element("xpath", f"""//*[@id="pdfArea"]/dl/dd/div[2]""").text summary_list.append(summary) # 상세 페이지 나오기 driver.find_element("xpath", """//*[@id="contents"]/article/div[1]/div[2]/a/span""").click() time.sleep(0.5) # 페이지 넘기기 if (page_num % 5) != 0: driver.find_element("xpath", f"""//*[@id="contents"]/article/div[4]/div[2]/ul/li[{page_num % 5 + 1}]/button""").click() else: driver.find_element("xpath", f"""//*[@id="contents"]/article/div[4]/div[2]/button[3]/span""").click() # 각 리스트에 있는 요소를 list_sum = list(zip(title_list, country_list, date_list, keyword_list, summary_list)) # 데이터 프레임의 칼럼명 생성 col = ["제목", "국가", "날짜", "키워드", "요약"] # 데이터 프레임 생성 df = pd.DataFrame(list_sum, columns=col) # 데이터 프레임 확인 df
notion imagenotion image

1.6 MySQL 연동 후 DB에 적재하기

1.6.1 MySQL 연동 후 DB에 적재하기

import MySQLdb conn = MySQLdb.connect( user="crawl_usr", passwd="", host="localhost", db="crawl_data" # charset="utf-8" ) print(type(conn)) # 커서 생성하기 cursor = conn.cursor() print(type(cursor)) # 실행할 때마다 다른값이 나오지 않게 테이블을 제거해두기 cursor.execute("DROP TABLE IF EXISTS kotra") # 테이블 생성하기 cursor.execute("CREATE TABLE kotra (title text, country text, date date, keyword text, summary text)") # 데이터 저장하기 for i in range(len(df)): cursor.execute( f"INSERT INTO kotra VALUES(\"{df.iloc[i]['제목']}\", \"{df.iloc[i]['국가']}\", \"{df.iloc[i]['날짜']}\", \"{df.iloc[i]['키워드']}\", \"{df.iloc[i]['요약']}\")" ) # 커밋하기 conn.commit() # 연결종료하기 conn.close()

1.6.2 DB 확인하기

# crawl_data 데이터베이스 사용 use crawl_data;
# news 테이블 생성 확인 show tables;
# news 테이블의 columns 확인 show columns from kotra from crawl_data;
# 데이터 확인 select * from kotra;
# 데이터 확인 select title, country, keyword from kotra;
notion imagenotion image