Prologue
API 및 웹 크롤링으로 데이터를 수집하는 2번째, 3번째 방법을 배웠고 그 내용을 기록할게요.
API
전체 과정
- URL로 웹사이트에 접근
- 파라미터 전달
- XML이나 HTML 값을 리턴 받기
- XML을 Element로 파싱
- Element를 통해 데이터프레임(딕셔너리 = {열 이름: 값 리스트}) 만들기
Requse로 XML 받기
API로 통신 = HTTP 통신
HTTP 통신하는 방법이 파이썬에서는 requests
모듈로 구현되어있음
우리는 데이터를 받기만 할거임(get 메소드만 사용)
데이터 추가(Post), 수정(Put), 삭제(Delete)는 이미 API 제공자가 해두셨음
- Url, Parameters 전달(허락받은 사용자라는 것을 인증하는 Service Key도
Parameters
에 포함)
# 실제 공공데이터 '전기자동차 충전소 정보' api로 가져오기
import requests
url = "http://apis.data.go.kr/B552584/EvCharger/getChargerInfo"
params = {'ServiceKey' : 'API 제공처에게 요청해서 받기'
,'pageNo' : '1'
,'numOfRows' : '10'
}
response = requests.get(url, params)
display(response.text)
Url = 요청주소(필수, API 제공자와 요청자가 만나는 장소)
Params = 요청변수(필수도 있고 옵션도 있음)
-> 출력결과(response)
response의 속성을 통해 원하는 정보 조회
response.text
: UTF-8로 인코딩된 문자열, xml 라이브러리를 통해 XML 객체로 바꿔야 함.response.status_code
: get 메서드에 대한 반응, 정상 작동(200)했는지 비정상 작동(4또는 5로 시작하는 숫자)했는지 알 수 있음
XML 파싱
- BeautifulSoup을 통해 계층구조 확인
# response 예쁘게 확인
# !pip install beautifulsoup4
# !pip install lxml # xml 데이터를 파싱해주기 위해 설치
from bs4 import BeautifulSoup
import lxml
# XML 파싱
soup = BeautifulSoup(response.text, 'xml')
# Pretty XML 출력
pretty_xml = soup.prettify()
print(pretty_xml)
- beautifulsoup을 설치하면 beautifulsoup3가 설치되니 조심. 꼭 4를 붙이자
- 설치 후 vscode 재시작을 통해 커널을 초기화 시킨다. 그래야 lxml을 인식함
아래 이미지를 다음 사진처럼 예쁜 구조로 변경 가능
- XML을 Element 객체로 파싱
# XML 파싱: 문자열(text) -> XML 트리 구조조 import xml.etree.ElementTree as ET
root = ET.fromstring(pretty_xml)
first_item = root.find(".//item")
dictionary = {child.tag.strip(): [] for child in first_item}
dictionary
1. ET 라이브러리를 통해 문자열을 XML 트리 구조로 바꾸면 XML의 태그 검색이 가능 -> 키 값과 열을 찾아서 DF로 만드는 과정을 코딩으로 할 수 있게됨
2. root는 XML 형태가 된 text 파일. XML 파일.
3. find(.//item)를 통해 첫번째 item 태그를 찾을 수 있음
.은 노드를 의미, /는 깊이를 의미, / 하나만 쓰면 바로 아래 계층에서만 찾고 // 두 개 쓰면 노드의 모든 하위 태그를 뒤져서 item을 찾음
4. df으로 만들 dictionary 생성, child tag를 키, 값은 [] 리스트로 만듦
.strip()은 문자열 양 쪽의 공백을 제거, 문자열의 공백은 제거하지 않음
### 딕셔너리에 값 채우기
```python
# XML의 태그 값을 딕셔너리 값에 넣기
import pandas as pd
for item in root.findall('.//item'):
for i in item:
dictionary[i.tag].append(i.text)
df = pd.DataFrame(dictionary)
df.head()
df에 값이 채워져있지만 \n이 양쪽에 붙어있음
앞 뒤 \n 제거
# 앞 뒤 \n 제거
df = df.map(lambda x: x.replace("\n", "").strip() if isinstance(x, str) else x)
display(df.loc[0, 'addr'], df.head(3))
(apply)map(lambda x: ~)를 통해 모든 셀에 함수를 적용
replace 함수를 통해 \n을 공백으로
참고: 위키독스, 파이썬노트
isinstance(x, str)을 통해 문자열에만 적용
str, list, int, float 등은 파이썬 내 자료형 클래스이므로 따옴표를 사용하지 않음
Spark 2주차
병렬 처리와 분산 처리
메모리가 감당 가능하다면 굳이 Spark 사용X, 연산을 최적화해야 함
파이썬에서는 멀티 쓰레딩이 아닌 멀티 프로세싱이 일반적임
- 멀티 프로세스는 독립된 메모리 공간을 가지고, 멀티 쓰레딩은 같은 메모리 공간을 공유함
파이썬에서 병렬 처리 패키지: Joblib
밥 한 번 먹고와야할 시간을 커피 한 잔 가져오는 시간 안에 끝내게 할 수 있음
약간 비효율적인 부분을 보완하려면 multiprocessing 패키지 사용, 다만 어려움
- 비효율적인 부분: 모든 코어가 작업이 끝나야 다 같이 그 다음 작업으로 넘어감
스파크 실습1
메모리를 효율적으로 사용하기
쓰지 않는 주피터 노트북, 크롬 등 파일은 끄기
함수를 사용하여 일시적으로 변수를 만들고 함수가 종료되면 그 변수를 삭제하기
함수가 실행되는 동안에만 메모리를 사용함
def extract_csvs():
res = []
for path in tqdm(glob("../app_review_data/*.csv")):
app_name = path.split("/")[-1].replace(".csv", "")
df_temp = pd.read_csv(path)
df_temp = df_temp.assign(app_name=app_name)
res.append(df_temp)
df = pd.concat(res)
return df
함수 내에서 선언된 app_name
, df_temp
등의 변수는 함수가 종료되면 삭제되고 출력값만이 나오게 된다.
폴더 내 파일 모두 하나의 df로 합치기
- glob으로 모든 .csv파일 선택
.. 모든 상위 디렉토리from glob import glob glob("../app_review_data/*.csv")
app_review_data 폴더 내의
*.csv: 모든 파일명 끝에 .csv가 있는 파일들의
파일 경로를 리스트로 만들어줌
- 모든 파일명의 파일을 하나로 통합
for 반복문의 리스트를 tqdm의 인자로 넣어서 진행률을 바에 표현되게 한다.def extract_csvs(): res = [] for path in tqdm(glob("../app_review_data/*.csv")): app_name = path.split("/")[-1].replace(".csv", "") df_temp = pd.read_csv(path) df_temp = df_temp.assign(app_name=app_name) res.append(df_temp) df = pd.concat(res) return df
app_name 열을 만들어주기 위해 각 파일명을 .csv를 빼고 읽은 후..
csv를 읽어서 df로 만든 후
df.assign(app_name=값)을 통해 app_name 컬럼을 생성하고 값을 채운다.df['app_name'] = 값
과 같음
pd.concat(리스트=res)로 모든 df를 합침
'Today I Learned' 카테고리의 다른 글
[TIL] 25.03.06 Postgre SQL 코드 테스트 대비 (0) | 2025.03.06 |
---|---|
[TIL] 25.03.05 SQLD와 SQL 그리고 구미시 버스 프로젝트 시작 (0) | 2025.03.05 |
[TIL] 25.02.26 데이터 분석가 취업 고민 및 조언 정리 (0) | 2025.02.27 |
[TIL] 25.02.25 프로젝트 발표 및 회고 (0) | 2025.02.25 |
[TIL] 25.02.24 실전 프로젝트 종료 (0) | 2025.02.25 |