ASAC-SK플래닛 T아카데미 데이터 엔지니어

25.11.25 34일차 [데이터 ETL level 3 마무리 | 데이터수집 레벨4]

Datadesigner 2025. 11. 25. 12:56

오늘은 데이터 ETL 과정 레벨 3 파트를 마무리 한 후 레벨 4 파트를 시작했다.

 


데이터 추출 및 변환 실습

  • 실습(리뷰시)
# 값이 없으면 0임
[
  {
    'exchange':'미국', # 통화국가
    'code':'USD', # 통화코드
    'std_rate': 1470.80, # 매매기준율
    'rate_per_d': 1.0 # 미화환산율
  }
  ,
  {

  }
  , ....
]

위 코드처럼 출력하시오

 

# 내 답

[{
    "exchange"  : exchange.string.strip().split(" ")[0],
    "code"      : exchange.select_one('a').get('href')[-6:-3],
    "std_rate"  : float(exchange_rate.text.replace(',','')),
    "rate_per_d": float(exchange_per.text.replace(',',''))
} for exchange,exchange_rate,exchange_per in zip(soup.select("td.tit"),soup.select("td.sale"),soup.select("td:nth-child(7)"))]

 

HTML에서 읽어오는 부분을 FOR IN ~ 부분에 집어넣어주고 이 항목들이 모두 같은 차수에서 돌 수 있게 ZIP()을 이용해서 묶어줬다. rate_per_d 부분의 html 부분은

크롬 개발자 모드 상의 copy selector 를 이용해서 찾아서 지정해주었다.

 

# 강사님 답

[{
    'exchange'      :tr.select_one('.tit').text.strip().split()[0],               # 통화국가
    'code'          :tr.select_one('.tit').select_one('a').get('href')[-6:-3],    # 통화코드
    'std_rate'      :float(tr.select_one('.sale').text.strip().replace(',','')),  # 매매기준율
    'rate_per_d'    :tr.select_one('td:nth-child(7)').text                        # 미화환산율    
}
 for tr in soup.select('.tbl_exchange > tbody > tr')
 ]

 

 

강사님은 for ~ in 뒤 부분의 html을 긁어올 부분을 나처럼 각각 나누지 않고 .tbl_exchange > tbody > tr로 가져왔다.

왜냐면 tr이 한 행의 모든 데이터를 가지고 있기 때문이다,

tr 행을 출력했을 때 모든 정보가 담겨있는 모습이다,

그 이후 tr에서 값을 긁어오고 다른 코드들은 똑같이 해주면 된다.

 

나는 각 항목마다 가져올 부분을 지정해주고 합쳤고

강사님은 가져올 부분을 한 부분에서 긁어온것이다. 그 차이

 

이렇게 level3 파트가 끝났다.

 


level 4

 

  • 타겟 사이트의 사람이 직접 개입하는 난이도가 높음
    • 검색, 클릭, 스크롤, 등등. . .
    • 로그인, 결과대기, js 사용 등등
    • 관찰
      • 버튼 클릭/메뉴 선택 -> 화면 껌뻑(주소창 x로 일시적 변환) -> form 전송
        • 기존에 특정한 요소(객체)들이 모두 초기화됨 (요소를 유지할 수 없음) -> 매번 새로 특정
      • 버튼 클릭/메뉴 선택 -> 화면 껌뻑(ajax통신) -> 비동기 백그라운드 통신
        • 유투브 리뷰 로드 (더보기,검색)

 


 

크롬드라이버를 먼저 다운받아준다.
본인 크롬과 버전을 맞춰준다

목표

 

오피넷 : https://www.opinet.co.kr/searRgSelect.do

각 지역마다 주유소를 표시해주는 사이트이다. 우리의 목표는

각 시/도

각 시/군/구 별로 위치한 주유소의 위치를

밑에 있는 엑셀저장까지 자동화하여 데이터를 추출하는것이다.

 

 

1. 폴더 생성 (CRAWING) / 라이브러리 다운로드

 

2. 데이터 수집(추출) 1단계 : 타겟 페이지 생성

코드 실행 시 타겟 페이지가 열린다.

3. 시도 정보 추출

개발자모드 SELECTOR로 확인한 모습이다.

id = SIDO_NMO에 모든 데이터가 있다, 위 코드를 이용해서 데이터를 추출해온다.

sido<select> 하위의 <option value>값을 가져오는것이다.

 

4. 시도 -> 시군구 데이터 출력

시도 를 타겟사이트에서 긁어와서 데이터를 추출해온다, 

이전 시도 데이터를 가져올때와 같은 방식으로 sigungu id에서 옵션 값들을 추출해온다.

 

작동 시 타겟 사이트도 같이 움직이는것을 확인할 수 있다.

 

 

 

 

5. 각 자치(시군구)를 순회하면서 -> 선택 -> 화면 재구성 대기 -> 엑셀 저장 버튼 클릭 -> 저장될때까지 대기

5-2-3부터 추가된 내용이다.

시군구 선택한 값이 나올때까지 대기, 이후 엑셀 저장버튼 클릭은 btn_type6_ex_save에서 가져오고 .click()함수를 이용한다.

엑셀저장 버튼 html상 내용,class 에서 참조해온다.
서울의 모든 자치구의 주유소 데이터를 받은 모습이다

 

6. 브라우저, 프로세스 종료

 

다 끝나면 종료해준다, 종료안하면 컴 터진다


데이터 변환 (xls -> DataFrame)

6-1 

 

 

glob 라이브러리를 사용, 현재 저장한 엑셀 파일 경로를 지정해준다

files 가 저 경로에 있는 모든 엑셀파일을 의미한다.

 

6-2

pandas 사용

6-3

1개만 잘 되는지 샘플링

xlrd 라이브러리를 다운받아주고 pandas를 이용해서 엑셀을 DataFrame으로 변환해준다.

이 때 엑셀파일 위쪽 두 줄은 필요없기 떄문에 header=2로 두번째줄부터 출력되는 코드를 추가해준다.

 

정상적으로 작동하니 dfs 변수에 for문을 이용해서 모든 df들을 담아준다.

 

 

병합 함수 concat()를 이용해서 서울시의 모든 주유소의 개수를 담아왔다. 총 412개 이다.

 

마지막으로 샘플 확인

 

level4 끝!

 

 

 


기타 level4 응용

 

유투브 댓글 볼 때면 밑으로 쭉 내리다가 스크롤이 로딩되어서 밑의 내용들이 더 나오는걸 본 적 있을거다.

 

이를 코드로 명령해본다.

 

 

driver 기능을 이용해서 java 함수를 사용할 수 있게 만들었다, 강제 스크롤 코드를 입력하고 실행한다면?

 

 

 

자동 스크롤 완성~

과제 나왔다...

 


데이터 준비 파트 _ numpy

개요

 

  • 용도
    • The fundamental package for scientific computing with Python
    • 파이썬에서 수치 계산과 과학 컴퓨팅을 위해 사용되는 기본 라이브러리
      • 수학, 과학용 라이브러리 + 푸리에 연산
    • 머신러닝/딥러닝 기반 기반 기술
  • 특징
    • 빠른 연산 (파이썬보다 빠름),
    • 효율적 메모리
    • 벡터 연산 (행렬 연산) 탁월하다
      • 벡터 -> 자연어를 표시 -> ... -> 벡터디비
  • 자료구조
    • 배열, ndarray (n차원 배열)
    • 배열의 구성원은 모두 동일한 타입

기본

 

numpy 기본 정보

배열 생성

 

 

  • 입력원(입력 데이터) 로부터 생성, 혹은 비어있는 배열
    • 입력원 : 리스트, 튜플, 다른 배열, Series, DataFrame, 기타
    • 출력값 : ndarray

array()

ndarray는 콤마가 없다.
차원 설명 이미지
한번 더 대괄호로 감사니까 2차원이 된 모습이다.

asarray()

얕은 카피와 깊은 카피에 주의할 것

 

arange()

 

 

 

오늘의 수업은 여기까지


아우 팔아퍼

 

작성할거 엄청 많다

 

최근 며칠 코드블럭으로 코드를 기입했는데 뭔가 가독성이 너무 안좋은거같아서 다시 캡쳐로 바꿨다. 뭐가 더 좋을까?

 

말 해줄 사람이 없으니 뭐 ㅋ.ㅋ 그냥 해야지

 

이번 파트는 꽤나 재미있다.

 

네이버 api까지만 해도 그냥 있는걸 가져오는 느낌에서 크게 벗어나진 않았었는데

 

본격적으로 주유소 정보를 직접 크롤링해보니까 어떤식으로 적용하는지, 이 코드와 키, 클래스 관련된 것들이 

 

어떻게 가져오고 작용하는지

 

이런 방법도 있구나 등등 신기한 것을 많이 보고 직접 실습해봐서 평소보다 체질에 조금 더 맞는 느낌이었다.

 

앞에서 해주시는거 보고 따라치기만 해서 그런가? 힝

 

지금은 강사님이 계시고 같이 해보기만 해서 잘 모르겠는데 이걸 혼자 어떻게 처음부터 만들어서 할까 생각해보면 엄두도 안 난다 그냥 라이브러리는 뭐가 이렇게 많고 명령어들도 뭐가 이렇게 많고 이걸 어떻게 다 외워서 하는지 참

 

데이터의 출처를 가져올때에도 정해진 한 가지 방법이 있는게 아니라 더 다양한 방법들이 있다.

 

나는 그래도 그런 점이 더 재미있었던 것 같다.

 

이렇게 점점 잘 맞는 부분을 찾는걸까, 아니면 그저 아직 안 막혀서 이러는걸까

 

그래도 이제 리스트컴프리핸션을 쓸 줄 알겠다.

 

그거 하나면 됐지 뭐~