1.1 사이트 소개1.2 해당 사이트 크롤링 목적1.3 크롤링 가능 여부 체크1.4 Kotra 사이트 구조 살펴보기1.4.1 첫 페이지 XPATH1.4.2 상세 페이지 XPATH1.4.3 다음 페이지 XPATH1.5 Kotra 해외 시장 상품 동향 크롤링하기 1.5.1 첫 페이지 크롤링하기1.5.2 상세 페이지 크롤링하기1.5.3 여러 페이지 크롤링하기1.6 MySQL 연동 후 DB에 적재하기1.6.1 MySQL 연동 후 DB에 적재하기1.6.2 DB 확인하기
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개의 게시글의 제목, 국가, 무역관, 게시일을 차례로 크롤링해보도록 하겠습니다.
- 필요한 라이브러리들을 불러와보도록 하겠습니다.
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 = []
- 제목, 국가, 무역관, 게시일에 해당하는 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)
- 위에서 수집한 내용들을 데이터프레임의 형태로 변환하도록 하겠습니다.
# 각 리스트에 있는 요소를 list_sum = list(zip(title_list, country_list, trade_list, date_list)) # 데이터 프레임의 칼럼명 생성 col = ["제목", "국가", "무역관", "날짜"] # 데이터 프레임 생성 df = pd.DataFrame(list_sum, columns=col) # 데이터 프레임 확인 df

- 최종 코드입니다.
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 상세 페이지 크롤링하기
현재 제목이 “중국 냉장고 시장 동향”, “태국 집적회로 시장 동향” 과 같이 제목만으로는 쉽게 내용을 파악할 수 없습니다. 따라서 상세 페이지 안으로 들어가 크롤링 해보도록 하겠습니다.
- 필요한 라이브러리들을 불러와보도록 하겠습니다.
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 = []
- 이후 자동으로 상세 페이지로 들어가서 필요한 부분을 크롤링한 후 상세 페이지를 빠져나와 다시 목록으로 돌아갈 수 있도록 하는 코드를 생성하도록 하겠습니다. 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()
- 위에서 수집한 내용들을 데이터프레임의 형태로 변환하도록 하겠습니다.
# 각 리스트에 있는 요소를 list_sum = list(zip(title_list, country_list, date_list, keyword_list, summary_list)) # 데이터 프레임의 칼럼명 생성 col = ["제목", "국가", "날짜", "키워드", "요약"] # 데이터 프레임 생성 df = pd.DataFrame(list_sum, columns=col) # 데이터 프레임 확인 df

- 최종 코드 입니다.
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번째 페이지까지 크롤링을 해보도록 하겠습니다.
- 페이지 구조를 보면, 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()
- 위의 코드를 앞선 최종 코드에 적용시켜보도록 하겠습니다. 페이지 이동한 후 동일하게 상세 페이지로 들어가서 필요한 요소를 크롤링하는 것을 반복하는 코드를 작성하겠습니다.
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

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;
