우리가 개선할 사항은 아래와 같습니다.
- 파일과 폴더 정리
- html파일에서 fetch api로 data 로딩
.js
파일이 아니라.json
으로 통신- 이를 위한 크롤러 개선
- yml 파일 수정
이렇게 파일을 수정하는 이유는 아래와 같습니다.
- 통상적 프로젝트의 폴더 관리
- .js파일은 python에서 파일 생성할 때 양식에 오류(예를 들어 text 안에 세미콜론이 있는 경우)가 있다하더라도 발견할 수 없음
- 무결성 검증을 json 라이브러리로 검사 가능(Action CI로 정상인지 테스트 할 수 있음)
이번 실습은 타이핑을 치는 실습이 아닙니다. 만약 프로젝트를 동일하게 가져가고 싶을 경우 이래 레파지토리에 코드를 다운로드 받으셔서 모두 덮어써주세요. 변경된 부분은 영상으로 설명드리도록 하겠습니다.
호스팅은 아래 URL에서 호스팅 되고 있습니다. 여기서 직접 코드를 확인하셔도 좋습니다. 메뉴에서 fetch 탭을 누르시면 fetch API를 사용하는 탭으로 이동합니다. UI는 동일합니다.
우리의 최종 폴더 tree는 아래와 같습니다.




- index.html에 추가 코드(메뉴에 탭 부분만 추가합니다.)
<li class="nav-item"> <a class="nav-link active" aria-current="page" href="fetch/">fetch</a> </li>
- 크롤러는
test.py
파일을 crawler 폴더에mainDataCrawler.py
파일로 변경
fetchDataCrawler.py
파일
import requests from bs4 import BeautifulSoup import csv import json response = requests.get("http://paullab.synology.me/stock.html") response.encoding = 'utf-8' html = response.text soup = BeautifulSoup(html, 'html.parser') oneStep = soup.select('.main')[2] twoStep = oneStep.select('tbody > tr')[1:] 날짜 = [] 종가 = [] 전일비 = [] 거래량 = [] 시가총액 = soup.select('#_market_sum')[0].text 시가총액순위 = soup.select('#_market_sum')[1].text 상장주식수 = soup.select('#_market_sum')[2].text 나머지값 = soup.select('tr > td') 배당수익률 = 나머지값[5].text.strip() 매출 = 나머지값[6].text 비용 = 나머지값[7].text 순익 = 나머지값[8].text for i in twoStep: 날짜.append(i.select('td')[0].text) 종가.append(int(i.select('td')[1].text.replace(',', ''))) 전일비.append(int(i.select('td')[2].text.replace(',', ''))) 거래량.append(int(i.select('td')[6].text.replace(',', ''))) l = [] for i in range(len(날짜)): l.append({ '날짜':날짜[i], '종가':종가[i], '전일비':전일비[i], '거래량':거래량[i], }) with open('json/fetchtestdata.json', "w", encoding="UTF-8-sig") as f_write: json.dump(l, f_write, ensure_ascii=False, indent=4) ll = [{ "이름" : "제주코딩베이스캠프", "시가총액" : 시가총액, "시가총액순위" : 시가총액순위, "상장주식수" : 상장주식수, "배당수익률" : 배당수익률, "매출" : 매출, "비용" : 비용, "순익" : 순익 }] with open('json/fetchtestbasicdata.json', "w", encoding="UTF-8-sig") as f_write: json.dump(ll, f_write, ensure_ascii=False, indent=4)
- fetch폴더에 index.html 파일에 script는 아래와 같습니다.
fetch('https://raw.githubusercontent.com/paullabkorea/recordGithubAction/main/json/fetchtestbasicdata.json').then(function(response){ response.json().then(function(basicdata){ document.getElementById('시가총액').innerHTML = '시가총액 : ' + basicdata[0].시가총액 + '억원' document.getElementById('시가총액순위').innerHTML = '시가총액순위 : ' + basicdata[0].시가총액순위 + '위' document.getElementById('상장주식수').innerHTML = '상장주식수 : ' + basicdata[0].상장주식수 + '주' document.getElementById('배당수익률').innerHTML = '배당수익률 : ' + basicdata[0].배당수익률 document.getElementById('매출').innerHTML = '매출 : ' + basicdata[0].매출 document.getElementById('비용').innerHTML = '비용 : ' + basicdata[0].비용 document.getElementById('순익').innerHTML = '순익 : ' + basicdata[0].순익 }) }) fetch('https://raw.githubusercontent.com/paullabkorea/recordGithubAction/main/json/fetchtestdata.json').then(function(response){ response.json().then(function(data){ let tableBodyData = []; for (let variable of data) { tableBodyData.push(` <tr> <td>${variable.날짜}</td> <td>${variable.종가}</td> <td>${variable.전일비}</td> <td>${variable.거래량}</td> </tr> `); } document.querySelector('.table > tbody').innerHTML = tableBodyData.join(''); let labels_chart_input = []; let data_chart_input = []; for (let variable of data) { labels_chart_input.push(variable.날짜) data_chart_input.push(variable.종가) } var config = { type: 'line', data: { labels: labels_chart_input, datasets: [{ label: '종가', backgroundColor: 'red', borderColor: 'red', data: data_chart_input, fill: false, }] }, options: { responsive: true, title: { display: true, text: '데이터 시각화' }, scales: { xAxes: [{ display: true, }], } } }; var ctx = document.getElementById('canvas').getContext('2d'); window.myLine = new Chart(ctx, config); }) })