늦게쓰는 미니 프로젝트 회고.
오늘은 23년 1월 30일.
22년 12월 19일에 시작했던 멋쟁이 사자처럼 AI스쿨 8기 과정이
시작한지 벌써 1/4 지점이 지난 시점.
지난 1월 18일에시작되고 1월 29일에 마무리 되었던 mini project 회고를 작성한다.
(과제 중간 작성하려 했으나, 실패... 다음부터는 중간 작성에 도전!)
mini project part.1 주제 : 웹 스크래핑 - 나라장터 '입찰 공고 목록 수집'
나라장터 (https://www.g2b.go.kr/index.jsp)
주제 선정 이유 : 기존에 학습했던 웹 스크래핑의 데이터 및 사이트는 모두 정형화 되어있는 포맷(틀)을 가지고 있어서
마지막 페이지와 table의 tag값, class명 등을 통해 '일괄' 수집 및 처리가 가능했다.
하지만 나라장터의 '입찰 공고' 목록은 업무의 종류, 공고기관, 계약방법 등에 따라
모두 상이한 데이터 테이블을의 형식을 가지고 있어, 이러한 데이터를 수집 및 가공에 성공한다면
차후 어떠한 사이트의 데이터도 웹 스크래핑을 할 수 있을 것 같다는 생각에
나라장터를 선정하게 되었다.
들어가기전에,
# 나라장터 웹 페이지 확인
나라장터의 첫 화면에 들어가면 '검색'의 방법이 2가지 존재한다.
위의 사진과 같이 일반 검색과 자세한 검색의 2가지 종류가 있는데,
일반적인 입찰 목록 확인은 노란 표시가 된 '검색'으로 진행해도 문제가 없으나
'웹 스크래핑' 관점에서 진행하면
해당 검색 기간 페이지가 모두 표기 되는 것이 아닌, 1개씩 추가로 보여지는 형식으로 구성되어 있어 '마지막' 페이지 확인이 불가능하다.
이는 또 하나의 검색 방법인 '자세한 검색'으로 해결이 가능한데,
페이지당 검색 목록수 조정 및 전체 검색 건수 표시 조건을 추가 할 수 있으며,
제일 중요한 '마지막' 페이지의 확인이 가능하다.
먼저 페이지가 이전과 달리 모두 표시 되며, '끝' 페이지 확인이 가능한 탭이 생성된다.
그리고 마지막 페이지인 488을 확인. (검색 조건 : 23.01.01 - 23.01.15 기간 모든 입찰 공고 목록 탐색)
2. 코드 작성
먼저 필요한 모듈 선언.
다음으로는 데이터 조회 일자를 변수 처리 및 f-string 변환.
검색 시작일/종료일 및 페이지 당 도출 목록 수를 모두 변수 처리 했다.
차후 사용을 위한 url 함수작성.
get을 통해 자료 요청을 했으며, status_code 체크를 통해
정상 출력 '200' 확인 진행
일차적으로 입찰 공고 목록 수집을 위한 데이터 처리 시작.
bs 적용 및 read_html로 table 구성 현황 및 내용을 체크
공고번호 확인 을 위한 tag 확인 및 'a' tag 수집을 위한 select 문 적용
공고번호 수집을 위한 list 반복문 생성. 이 과정에서 특이점은 한 공고당 공고번호와 공고번호 + 공고명의 2가지 공고번호가 산출되어, index % 2 = 0으로 1개를 도출하도록 구성했다. (이 부분은 조원인 강섭님 아이디어를 적용)
한 페이지 수집 함수를 작성 했으며
제일 우측에 '상세페이지' 컬럼 및 공고번호가 나열된 것을 확인.
여기까지는 기존 수업시간에 배운 내용의 적용이라 시간 소요가 거의 없었다.
하지만...
part 1. 웹 스크래핑의 과제는 이제부터 시작.
상세페이지의 내용 수집에서 팀 프로젝트의 고난을 맞이하였다.
우선, 제일 먼저 떠오른 고민은
'기존의 데이터를 수집하여 어떤 결과물을 도출 할 것인가?' 에 대한 고민이었다.
(현재 나라장터 사이트에서 제공 되는 현황은 위의 여러 스크린샷을 통해 확인 가능하다. )
데이터 웹 스크래핑을 통해, 누군가에게 효용이 있는 '쓸 수 있는' 자료를 도출 하는 것을 목표로
상세페이지의 내용 추가 및 기존 컬럼 삭제, 재 배열을 구상했다.
위의 컬럼은 과제 수행 2일차에 작성했던
블로그 글에서 확인 가능.
https://coderedapple.tistory.com/38
그리고 팀원들과의 고난이 시작되었다.
입찰 공고 목록의 효율성을 위해 상세페이지(1차페이지에서 연결되는 하위페이지)에서
'재입찰' 가능 여부와, '금액' 부분을 공고명과 같이 나열하려 했으나
업무에 따라, 공고기관에 따라, 계약방법에 따라
'재입찰' 항목 테이블의 배열(위치)이 모두 상이한 것.
여기까지는... 그래 그럴 수 있지. 하며 넘어갔으나
정말 끝판왕은 '가격' 이었다.
추정가격, 추정금액, 사업금액 등등....
공고인이 본인들이 편하게 '금액' 명을 모두 다르게 표기했으며
추정금액과 사업금액은 tax를 포함하는 경우와 미 포함이 랜덤하게 적용되어 있었다.
위의 자료는 이번 프로젝트 데이터 중 마지막 항목의 데이터인데
제일 '형식'을 갖춘 데이터였다.
재입찰 여부가 존재하며, 추정 가격 등 금액 부분이 존재하는.
'업무' 항목 미 등록 및 '계약방법' 이 미 존재하는 항목들은 null 처리 가능하므로 pass 가능하나
재입찰 및 금액 항목이 아에 없는 데이터는 물론,
재입찰 항목은 존재하나, 테이블의 위치가 상이한 데이터 등등이 존재하여
'재입찰' 과 '추정가격' 데이터 수집에 1주일의 시간을 투자 했다.
조원들 모두가 각기 다른 코드로 수집에 도전했고,
나는 그 중 '전치행렬'을 이용해 코드 수집을 시도했다.
read_html을 통해 테이블에서 '재입찰' 존재를 체크
.
전치행렬 적용으로 '재입찰'을 컬럼명으로 변환.
동일 과정을 반복하여 '추정가격'을 체크 및 컬럼화.
concat을 통해 추출 항목을 병합 처리.
전치행렬 처리 함수를 작성.
상세페이지 내용 수집 함수 작성.
14600여개의 데이터 처리 전 10개의 데이터에 해당 함수 적용.
공고목록 수집 내용과 상세페이지 내용 병합.
reset_index 처리 후 병합을 진행했으나, 최종 결과치에는 index가 맞지 않게 도출 되었으며,
최초 가장 규격화 되어있던 공고목록 기준 전치행렬 처리 함수에서
'재입찰' 및 '추정가격' 검색 실패로 nan 도출이 되었다.
당시에 든 생각은, 전치행렬 함수 생성시, 반복문 함수를 추가하여
모든 테이블에서 조건을 검색 하도록 하는 방안을 고민했는데,
과제가 마무리 된 오늘날에는, 차라리 상세페이지 내 모든 테이블을 병합, 전치행렬 처리하여
해당 조건을 검색하는 것이 보다 효율적일 것 같다는 생각을 한다.
무튼, 전치행렬 처리로 도전했던 해당 과제는 여기서 마무리.
조원들의 코드로 해당 과제는 '성공적'으로 마무리 했다.
방법은 read_html에 있는 모든 항목을 대상으로
컬럼을 대입, 열을 먼저 찾은 후 고정, 이후 행을 찾아
열 +1을 통해 재입찰 여부의 내용을 반환 하는 것. (희묵님 코드)
추정가격 역시 동일 과정 반복 수행
최종 결과물은 성공적.
글을 마치며.
웹 스크래핑 - 나라장터 공고 목록 수집 과정에서 어려웠던 부분은
1차 페이지에서 이어지는 하위 페이지 테이블의 배열 및 숫자가
일정한 포맷이 없는 상태로 웹 페이지가 구성되어 있어서 1차 페이지의 수집은 무난하나,
하위 페이지의 원하는 탐색 조건 설정이 난해한 점이었다.
또한, 시도했으나 실패했던 부분은
1차 페이지 수집 이후 하위 테이블의 내용을 전치행렬로 모두 이어 붙여,
원하는 테이블 명 선택이 가능 할 것이라 예상 했으나,
페이지마다 ‘테이블 수’와 ‘테이블 명’ 그리고 ‘테이블 위치’ 등 규격화 된 양식이 존재 하지 않아
전치행렬 처리를 완료하지 못점.
(head 10개는 나름 결과물 도출에 성공했으나 이후 전체 데이터 적용시 결측치 다수 발생)
마지막으로
웹 스크래핑 프로젝트를 진행하며 느낀점은.
'언젠가 코딩도 공부처럼 앉은 시간에 비례해 성장한다'는 문구를 본 적이 있다.
짧고도 길었던 이번 미니 프로젝트 기간 동안, 코드에 대한 고민과 이해를 많이 할 수 있었던 시간이었고,
무엇보다도 프로젝트의 ‘주제와 목적 의식’에 대한 많은 생각들을 통해 향후
‘어떠한 마인드로 분석 과정에 임해야 하는지’를 스스로 되돌아 볼 수 있었던 시간이었다.
또한, 아직 배우지 못했던 ‘시각화’ 부분을 준비하며, 한 가지의 시각화 방법으로도 다양한 결과 도출이 가능한 점과 시각화 결과의 ‘가독성’과 ‘적시성’에 대한 생각을 갖게 되었으며 , 그 동안 학습했던 코드를 적용하며 팀원들과 보다 효율인
코드를 찾는 과정에서 ‘팀워크 및 팀플레이’에 대한 부분도 배울 수 있었던 뜻 깊은 시간이었다.
로 마무리.
제출용 답변으로 회고 끝.
'멋쟁이사자처럼 AI School 8기(fin)' 카테고리의 다른 글
[멋쟁이사자처럼 AI스쿨] 통계 3일차 회고 (1) | 2023.02.16 |
---|---|
[멋쟁이사자처럼] 통계학 day2 정리 (0) | 2023.02.15 |
[멋쟁이사자처럼 AI스쿨] mini-project2 with EDA 회고 (0) | 2023.02.06 |
[멋쟁이사자처럼 AI스쿨] mini project #1-2. API (0) | 2023.01.30 |
[멋쟁이사자처럼 AI스쿨 8기] 멋쟁이 사자처럼 데이터 분석 코스 (0) | 2022.12.19 |