크롤링을 하기 위해서 python, html, css를 이해하는 것이 선제되어야 합니다.
(주의) 밑의 코드는 네이버 블로그를 크롤링 한 파일입니다. 네이버에서 내부 클래스 명이 자주 바뀌므로 동작하지 않을 수 있습니다.
필요성 네이버 지도를 통한 데이터를 가져올때 모든 데이터를 하나씩 입력하는 것이 오랜 시간이 걸립니다.
또한 데이터를 다양하게 수집해 필터링 한다면 데이터를 유용하게 관리할 수 있다는 판단하에 시작하게 되었습니다.
우선 검색어를 필터링 하기 위해 시도 정보를 가져옵니다.
시도 정보 가져오기
import requests
import json
import xml.etree.ElementTree as ET
import os
url = 'http://api.vworld.kr/req/data'
params = {
'service': 'data',
'request': 'GetFeature',
'data': 'LT_C_ADSIDO_INFO',
'key': "개인 키",
'geometry': 'false',
'size': '100',
'geomFilter': 'BOX(124,33,132,43)'
}
try:
# API 요청 보내기
response = requests.get(url, params=params)
response.raise_for_status() # HTTP 에러 발생 시 예외 발생
# JSON 데이터 파싱
data = response.json()
# ctp_kor_nm 값 추출하여 리스트로 저장
ctp_kor_nm_list = [feature['properties']['ctp_kor_nm'] for feature in data['response']['result']['featureCollection']['features']]
# 결과 출력
print(ctp_kor_nm_list)
except requests.exceptions.RequestException as e:
print('API 요청 중 오류 발생:', e)
except KeyError as e:
print('JSON 데이터 파싱 중 오류 발생 - 필드가 존재하지 않음:', e)
except Exception as e:
print('오류 발생:', e)
root = ET.Element("data")
try:
for ctp_kor_nm in ctp_kor_nm_list:
# API 요청 파라미터 설정
params = base_params.copy()
params['attrFilter'] = f"full_nm:like:{ctp_kor_nm}"
# API 요청 보내기
response = requests.get(url, params=params)
response.raise_for_status() # HTTP 에러 발생 시 예외 발생
# JSON 데이터 파싱
data = response.json()
# XML에 데이터 추가
for feature in data['response']['result']['featureCollection']['features']:
item = ET.SubElement(root, "item")
ctp_kor_nm_elem = ET.SubElement(item, "ctp_kor_nm")
ctp_kor_nm_elem.text = ctp_kor_nm
sig_kor_nm = ET.SubElement(item, "sig_kor_nm")
sig_kor_nm.text = feature['properties']['sig_kor_nm']
except requests.exceptions.RequestException as e:
print('API 요청 중 오류 발생:', e)
except KeyError as e:
print('JSON 데이터 파싱 중 오류 발생 - 필드가 존재하지 않음:', e)
except Exception as e:
print('오류 발생:', e)
else:
# XML 파일 저장
desktop_path = os.path.expanduser("~/Desktop")
xml_filename = os.path.join(desktop_path, "sigg_data.xml")
tree = ET.ElementTree(root)
tree.write(xml_filename, encoding='utf-8', xml_declaration=True)
print(f"XML 파일이 {xml_filename}에 저장되었습니다.")
# ctp_kor_nm_list를 저장할 sido.xml 파일 생성 및 저장
sido_root = ET.Element("sido")
for ctp_kor_nm in ctp_kor_nm_list:
ctp_kor_nm_elem = ET.SubElement(sido_root, "ctp_kor_nm")
ctp_kor_nm_elem.text = ctp_kor_nm
sido_xml_filename = os.path.join(desktop_path, "sido.xml")
sido_tree = ET.ElementTree(sido_root)
sido_tree.write(sido_xml_filename, encoding='utf-8', xml_declaration=True)
print(f"XML 파일이 {sido_xml_filename}에 저장되었습니다.")
일반적으로 프론트와 백을 같은 언어로 하는 프레임워크는 적다.
NodeJS는 JavaScript로 서버단 로직을 처리할 수 있다.
다만, 비동기 방식으로 처리하기 때문에 설계와 콜백에 주의를 해야한다.
cloud native spring in action chapter 14장을 참고한 글입니다.
설명 내용
쿠버네티스에서 애플리케이션 설정
컨피그 맵과 시크릿 사용
커스터마이즈를 통한 배포 및 설정 관리 방법
애플리케이션과 함께 패키징 되는 속성파일의 종류
환경 변수 : 호스트 이름, 서비스 이름, 포트 번호 등
설정 서비스 : 스레드 풀, 시간 초과 타임 등
우선 설정 전략을 설정할 config server도 HTTP로 접근합니다.
따라서 권한 부여된 상대에게만 접속하기 위해 OAuth2 Client Credential 흐름으로 Access Token 기반 보호를 적용합니다.
하지만 Https 통신을 한다면 자체적인 설정 속성이 암호화 되지 않더라도 응답은 암호화 되므로 안전합니다.
기존에 단일 서버라면 /actuator/refresh 엔드 포인트에 POST 요청을 통해서 새로고침을 트리거 할수 있습니다.
하지만 모든 인스턴스에 트리거를 하나씩 보낼수 없기 때문에 Spring Cloud Bus를 이용합니다.
즉, 변경된 코드를 수정하면 설정 데이터 저장소에서 웹훅으로 트리거를 보냅니다.
그리고 컨피그 서비스가 웹훅을 받으면 설정 변경 이벤트를 각 서비스에 전송하고 각 서비스에서 이벤트를 처리하는 방식입니다.
또한 변경 사항은 다시 config service에서 브로드케스팅합니다.
Mac에서 IntelliJ 단축키 모두 알고 계신가요?
보통 사용하는 키만 사용하고 나머지는 사용하지 않고 계신건 아닌가요?
Tobby님의 강연을 들으면서 IntelliJ에 대해 얼마나 자세히 알고 있는지 물어보셨을때
매일 쓰면서도 자세히 모른다는 사실을 직면했습니다.
한번 알아볼게요
우선 jet brain 사이트로로 가시면 자세히 설명되어 있는 것을 알수 있습니다.
command + , 를 통해 설정창으로 들어갑니다. → 색맹, 커스텀 ui, keymap(short key)등 수정가능 합니다.
command + d 를 파일 2개를 클릭한 상태에서 실행하면 2 파일의 코드를 비교합니다.