[고급] 부동산 정보 필터 고도화 ㅣ 그 동안 부동산 정보 크롤링 코드를 모아서 좀 더 고도화 하는 작업을 하도록 해볼게요. 우선 네이버에서 “서울특별시” 를 입력할 경우 모든 법정동을 조회하여 법정동에 헤당하는 아파트를 먼저 모아 오도록 하겠습니다. 법정동에 포함된 아파트 정보를 수집하여 분석할 수 있는 raw data를 만들고 제 기준에 따라 매물을 정리해보도록 하겠습니다.
2024.09.14 – [부동산/자동화 프로젝트] – 파이썬 부동산 매매가 조회 프로그램 만들기 2편 (지역코드)
2024.09.15 – [부동산/자동화 프로젝트] – 부동산 매물 정보 수집하기 – 부동산 데이터 네이버 부동산 크롤링 및 가공 #2
부동산 매매가 조회편과 부동산 매물 정보 수집 편을 확인하면, 아래 코드를 수정하는데 어려움이 없으 실 겁니다.
import requests
import json
import pandas as pd
from datetime import datetime
def get_dong_codes_for_city(city_name, json_path):
try:
with open(json_path, 'r', encoding='utf-8') as file:
data = json.load(file)
except FileNotFoundError:
print(f"Error: The file at {json_path} was not found.")
return None, None
for si_do in data:
if si_do['si_do_name'] == city_name:
sigungu_codes = [sigungu['sigungu_code'] for sigungu in si_do['sigungu']]
dong_codes = [
{
'code': dong['code'],
'name': dong['name']
}
for sigungu in si_do['sigungu']
for dong in sigungu['eup_myeon_dong']
]
return sigungu_codes, dong_codes
return None, None
def get_apt_list(dong_code):
down_url = f'https://new.land.naver.com/api/regions/complexes?cortarNo={dong_code}&realEstateType=APT&order='
header = {
"Accept-Encoding": "gzip",
"Host": "new.land.naver.com",
"Referer": "https://new.land.naver.com/complexes/102378?ms=37.5018495,127.0438028,16&a=APT&b=A1&e=RETAIL",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
}
try:
r = requests.get(down_url, headers=header)
r.encoding = "utf-8-sig"
data = r.json()
if 'complexList' in data and isinstance(data['complexList'], list):
df = pd.DataFrame(data['complexList'])
# 추가 정보 포함 (예: 건축년도, 세대수, 평수 등)
required_columns = ['complexNo', 'complexName', 'buildYear', 'totalHouseholdCount', 'areaSize', 'price', 'address', 'floor']
# 필요한 컬럼만 추출 (없으면 기본값 설정)
for col in required_columns:
if col not in df.columns:
df[col] = None
return df[required_columns]
else:
print(f"No data found for {dong_code}.")
return pd.DataFrame(columns=['complexNo', 'complexName', 'buildYear', 'totalHouseholdCount', 'areaSize', 'price', 'address', 'floor'])
except Exception as e:
print(f"Error fetching data for {dong_code}: {e}")
return pd.DataFrame(columns=['complexNo', 'complexName', 'buildYear', 'totalHouseholdCount', 'areaSize', 'price', 'address', 'floor'])
def collect_apt_info_for_city(city_name, json_path):
sigungu_codes, dong_list = get_dong_codes_for_city(city_name, json_path)
if dong_list is None:
print(f"Error: {city_name} not found in JSON.")
return None
all_apt_data = []
dong_code_name_map = {dong['code']: dong['name'] for dong in dong_list}
for dong_code, dong_name in dong_code_name_map.items():
print(f"Collecting data for {dong_code} ({dong_name})")
apt_data = get_apt_list(dong_code)
if not apt_data.empty:
apt_data = apt_data.copy() # 데이터프레임 복사본을 생성
apt_data['dong_code'] = dong_code
apt_data['dong_name'] = dong_name
all_apt_data.append(apt_data)
else:
print(f"No data found for {dong_code}")
if all_apt_data:
final_df = pd.concat(all_apt_data, ignore_index=True)
final_df['si_do_name'] = city_name
final_df['sigungu_name'] = final_df['dong_code'].apply(lambda x: x[:5]) # sigungu_name 추출
final_df['dong_name'] = final_df['dong_name'].apply(lambda x: x) # 동 이름 적용
final_df = final_df[['si_do_name', 'sigungu_name', 'dong_name', 'complexNo', 'complexName', 'buildYear', 'totalHouseholdCount', 'areaSize', 'price', 'address', 'floor']]
return final_df
else:
return pd.DataFrame(columns=['si_do_name', 'sigungu_name', 'dong_name', 'complexNo', 'complexName', 'buildYear', 'totalHouseholdCount', 'areaSize', 'price', 'address', 'floor'])
def save_to_excel(df, city_name):
now = datetime.now().strftime("%Y%m%d_%H%M%S")
file_name = f"{city_name}_{now}.xlsx"
file_path = f'/content/drive/MyDrive/{file_name}'
df.to_excel(file_path, index=False)
print(f"Data saved to {file_path}")
# 사용자 입력 받기
city_name = input("Enter the city or province name: ")
json_path = '/content/drive/MyDrive/district.json' # 올바른 JSON 파일 경로로 수정하십시오.
# 아파트 정보 수집
apt_data = collect_apt_info_for_city(city_name, json_path)
if apt_data is not None:
print(apt_data)
save_to_excel(apt_data, city_name)
else:
print("No data collected.") 이제 이 코드를 실행해서 어떻게 나오는지 확인해볼까요? 서울특별시 각 구에 속해 있는 아파트 리스트를 아래와 같이 잘 출력하는 것을 확인했습니다. 이제 각 아파트 정보를 옆에 추가적으로 넣어 보도록하겠습니다.
이 데이터에 아파트별 정보를 추가로 넣는 작업을 하면 아래 코드와 같습니다
import requests
import json
import pandas as pd
from datetime import datetime
from bs4 import BeautifulSoup
def get_dong_codes_for_city(city_name, json_path):
try:
with open(json_path, 'r', encoding='utf-8') as file:
data = json.load(file)
except FileNotFoundError:
print(f"Error: The file at {json_path} was not found.")
return None, None
for si_do in data:
if si_do['si_do_name'] == city_name:
sigungu_codes = [sigungu['sigungu_code'] for sigungu in si_do['sigungu']]
dong_codes = [
{
'code': dong['code'],
'name': dong['name']
}
for sigungu in si_do['sigungu']
for dong in sigungu['eup_myeon_dong']
]
return sigungu_codes, dong_codes
return None, None
def get_apt_codes(dong_code):
down_url = f'https://new.land.naver.com/api/regions/complexes?cortarNo={dong_code}&realEstateType=APT&order='
header = {
"Accept-Encoding": "gzip",
"Host": "new.land.naver.com",
"Referer": "https://new.land.naver.com/complexes/102378?ms=37.5018495,127.0438028,16&a=APT&b=A1&e=RETAIL",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
}
try:
r = requests.get(down_url, headers=header)
r.encoding = "utf-8-sig"
data = r.json()
if 'complexList' in data and isinstance(data['complexList'], list):
apt_codes = [complex_info['complexNo'] for complex_info in data['complexList']]
return apt_codes
else:
print(f"No data found for {dong_code}.")
return []
except Exception as e:
print(f"Error fetching apartment codes for {dong_code}: {e}")
return []
def get_apt_details(apt_code):
details_url = f'https://fin.land.naver.com/complexes/{apt_code}?tab=complex-info'
header = {
"Accept-Encoding": "gzip",
"Host": "fin.land.naver.com",
"Referer": "https://fin.land.naver.com/",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
}
try:
r = requests.get(details_url, headers=header)
r.encoding = "utf-8-sig"
soup = BeautifulSoup(r.content, 'html.parser')
# Extract complex details
detail_dict = {'complexNo': apt_code}
detail_items = soup.find_all('li', class_='DataList_item__T1hMR')
for item in detail_items:
term = item.find('div', class_='DataList_term__Tks7l').text.strip()
definition = item.find('div', class_='DataList_definition__d9KY1').text.strip()
if term in ['공급면적', '전용면적', '해당면적 세대수', '현관구조', '방/욕실']:
detail_dict[term] = definition
return detail_dict
except Exception as e:
print(f"Error fetching details for {apt_code}: {e}")
return {}
def collect_apt_info_for_city(city_name, json_path):
sigungu_codes, dong_list = get_dong_codes_for_city(city_name, json_path)
if dong_list is None:
print(f"Error: {city_name} not found in JSON.")
return None
all_apt_data = []
dong_code_name_map = {dong['code']: dong['name'] for dong in dong_list}
for dong_code, dong_name in dong_code_name_map.items():
print(f"Collecting apartment codes for {dong_code} ({dong_name})")
apt_codes = get_apt_codes(dong_code)
if apt_codes:
for apt_code in apt_codes:
print(f"Collecting details for {apt_code}")
apt_details = get_apt_details(apt_code)
if apt_details:
apt_details['dong_code'] = dong_code
apt_details['dong_name'] = dong_name
all_apt_data.append(apt_details)
else:
print(f"No apartment codes found for {dong_code}")
if all_apt_data:
final_df = pd.DataFrame(all_apt_data)
final_df['si_do_name'] = city_name
final_df['sigungu_name'] = final_df['dong_code'].apply(lambda x: x[:5]) # sigungu_name 추출
final_df['dong_name'] = final_df['dong_name'].apply(lambda x: x) # 동 이름 적용
final_df = final_df[['si_do_name', 'sigungu_name', 'dong_name', 'complexNo', '공급면적', '전용면적', '해당면적 세대수', '현관구조', '방/욕실']]
return final_df
else:
return pd.DataFrame(columns=['si_do_name', 'sigungu_name', 'dong_name', 'complexNo', '공급면적', '전용면적', '해당면적 세대수', '현관구조', '방/욕실'])
def save_to_excel(df, city_name):
now = datetime.now().strftime("%Y%m%d_%H%M%S")
file_name = f"{city_name}_{now}.xlsx"
file_path = f'/content/drive/MyDrive/{file_name}'
df.to_excel(file_path, index=False)
print(f"Data saved to {file_path}")
# 사용자 입력 받기
city_name = input("Enter the city or province name: ")
json_path = '/content/drive/MyDrive/district.json' # 올바른 JSON 파일 경로로 수정하십시오.
# 아파트 정보 수집
apt_data = collect_apt_info_for_city(city_name, json_path)
if apt_data is not None:
print(apt_data)
save_to_excel(apt_data, city_name)
else:
print("No data collected.") 서울특별시 전체 동에 대한 정보를 수집하는 것은 꽤 시간이 오래 걸립니다. 서울특별시 전체 동에 대한 정보가 아닌 특정 구까지 입력받아서 조사하도록 수정해보겠습니다. 그리고 만약 전체 구를 조사하고 싶으면 전체 라고 입력할 경우 전체 구에 포함된 법정동을 조사하도록 수정합니다.
import requests
import json
import pandas as pd
from datetime import datetime
from bs4 import BeautifulSoup
# 시/도와 구 정보를 JSON 파일에서 불러오는 함수
def get_dong_codes_for_city(city_name, json_path, sigungu_name=None):
try:
with open(json_path, 'r', encoding='utf-8') as file:
data = json.load(file)
except FileNotFoundError:
print(f"Error: The file at {json_path} was not found.")
return None, None
for si_do in data:
if si_do['si_do_name'] == city_name:
all_sigungu = si_do['sigungu']
if sigungu_name and sigungu_name != "전체":
for sigungu in all_sigungu:
if sigungu['sigungu_name'] == sigungu_name:
dong_codes = [
{
'code': dong['code'],
'name': dong['name']
}
for dong in sigungu['eup_myeon_dong']
]
return [sigungu['sigungu_code']], dong_codes
else: # 전체 구를 선택한 경우
sigungu_codes = [sigungu['sigungu_code'] for sigungu in all_sigungu]
dong_codes = [
{
'code': dong['code'],
'name': dong['name']
}
for sigungu in all_sigungu
for dong in sigungu['eup_myeon_dong']
]
return sigungu_codes, dong_codes
return None, None
# 법정동 코드로 아파트 코드를 가져오는 함수
def get_apt_codes(dong_code):
down_url = f'https://new.land.naver.com/api/regions/complexes?cortarNo={dong_code}&realEstateType=APT&order='
header = {
"Accept-Encoding": "gzip",
"Host": "new.land.naver.com",
"Referer": "https://new.land.naver.com/complexes/102378?ms=37.5018495,127.0438028,16&a=APT&b=A1&e=RETAIL",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
}
try:
r = requests.get(down_url, headers=header)
r.encoding = "utf-8-sig"
data = r.json()
if 'complexList' in data and isinstance(data['complexList'], list):
apt_codes = [complex_info['complexNo'] for complex_info in data['complexList']]
return apt_codes
else:
print(f"No data found for {dong_code}.")
return []
except Exception as e:
print(f"Error fetching apartment codes for {dong_code}: {e}")
return []
# 아파트 코드로 상세 정보를 가져오는 함수
def get_apt_details(apt_code):
details_url = f'https://fin.land.naver.com/complexes/{apt_code}?tab=complex-info'
header = {
"Accept-Encoding": "gzip",
"Host": "fin.land.naver.com",
"Referer": "https://fin.land.naver.com/",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
}
try:
r = requests.get(details_url, headers=header)
r.encoding = "utf-8-sig"
soup = BeautifulSoup(r.content, 'html.parser')
# Extract complex details
detail_dict = {'complexNo': apt_code}
detail_items = soup.find_all('li', class_='DataList_item__T1hMR')
for item in detail_items:
term = item.find('div', class_='DataList_term__Tks7l').text.strip()
definition = item.find('div', class_='DataList_definition__d9KY1').text.strip()
if term in ['공급면적', '전용면적', '해당면적 세대수', '현관구조', '방/욕실']:
detail_dict[term] = definition
return detail_dict
except Exception as e:
print(f"Error fetching details for {apt_code}: {e}")
return {}
# 도시와 구별로 아파트 정보를 수집하는 함수
def collect_apt_info_for_city(city_name, json_path, sigungu_name=None):
sigungu_codes, dong_list = get_dong_codes_for_city(city_name, json_path, sigungu_name)
if dong_list is None:
print(f"Error: {city_name} or {sigungu_name} not found in JSON.")
return None
all_apt_data = []
dong_code_name_map = {dong['code']: dong['name'] for dong in dong_list}
for dong_code, dong_name in dong_code_name_map.items():
print(f"Collecting apartment codes for {dong_code} ({dong_name})")
apt_codes = get_apt_codes(dong_code)
if apt_codes:
for apt_code in apt_codes:
print(f"Collecting details for {apt_code}")
apt_details = get_apt_details(apt_code)
if apt_details:
apt_details['dong_code'] = dong_code
apt_details['dong_name'] = dong_name
all_apt_data.append(apt_details)
else:
print(f"No apartment codes found for {dong_code}")
if all_apt_data:
final_df = pd.DataFrame(all_apt_data)
final_df['si_do_name'] = city_name
final_df['sigungu_name'] = final_df['dong_code'].apply(lambda x: x[:5]) # sigungu_name 추출
final_df['dong_name'] = final_df['dong_name'].apply(lambda x: x) # 동 이름 적용
final_df = final_df[['si_do_name', 'sigungu_name', 'dong_name', 'complexNo', '공급면적', '전용면적', '해당면적 세대수', '현관구조', '방/욕실']]
return final_df
else:
return pd.DataFrame(columns=['si_do_name', 'sigungu_name', 'dong_name', 'complexNo', '공급면적', '전용면적', '해당면적 세대수', '현관구조', '방/욕실'])
# 엑셀 파일로 저장하는 함수
def save_to_excel(df, city_name, sigungu_name=None):
now = datetime.now().strftime("%Y%m%d_%H%M%S")
if sigungu_name and sigungu_name != "전체":
file_name = f"{city_name}_{sigungu_name}_{now}.xlsx"
else:
file_name = f"{city_name}_전체_{now}.xlsx"
file_path = f'/content/drive/MyDrive/{file_name}'
df.to_excel(file_path, index=False)
print(f"Data saved to {file_path}")
# 사용자 입력 받기
city_name = input("Enter the city or province name (e.g., 서울특별시): ")
sigungu_name = input("Enter the district (gu) name or type '전체' for all districts: ")
json_path = '/content/drive/MyDrive/district.json' # 올바른 JSON 파일 경로로 수정하십시오.
# 아파트 정보 수집
apt_data = collect_apt_info_for_city(city_name, json_path, sigungu_name)
if apt_data is not None:
print(apt_data)
save_to_excel(apt_data, city_name, sigungu_name)
else:
print("No data collected.") 잘 동작은 합니다만, 여전히 구에 포함된 아파트도 너무 많죠? 시간이 많이 걸리네요, 이제는 특정 시, 구, 동까지 선택할 수 있도록 더 수정해봅니다.
수정을 하면서, 아파트명이 누락되어 있기 때문에 아파트명도 포함시키도록 하겠습니다. 즉 법정동도 선택할 수 있도록 할 예정인데
예를 들어, 서울특별시, 마포구, 아현동까지 법정동을 선택하면 법정동만 조사하고, 전체 라고 선택하면 전체를 조사하게 되는 것입니다. 시/군, 법정동 각각 전체를 입력으면서 만약 시군구를 전체라고 입력하면 법정동은 자동으로 입력 받을 필요 없이 전체를 조사하게 됩니다. 그리고 조사자료에 아파트명이 빠져 있는데 아파트 코드명 옆 열에 아파트 명을 넣을 예정입니다.
from google.colab import drive
import requests
import json
import pandas as pd
from datetime import datetime
from bs4 import BeautifulSoup
# Google Drive 마운트
drive.mount('/content/drive')
# 법정동 코드를 가져오는 함수
def get_dong_codes_for_city(city_name, sigungu_name=None, json_path='/content/drive/MyDrive/district.json'):
try:
with open(json_path, 'r', encoding='utf-8') as file:
data = json.load(file)
except FileNotFoundError:
print(f"Error: The file at {json_path} was not found.")
return None, None
for si_do in data:
if si_do['si_do_name'] == city_name:
if sigungu_name and sigungu_name != '전체':
for sigungu in si_do['sigungu']:
if sigungu['sigungu_name'] == sigungu_name:
return [sigungu['sigungu_code']], [
{'code': dong['code'], 'name': dong['name']} for dong in sigungu['eup_myeon_dong']
]
else: # 시군구 '전체'
sigungu_codes = [sigungu['sigungu_code'] for sigungu in si_do['sigungu']]
dong_codes = [
{'code': dong['code'], 'name': dong['name']}
for sigungu in si_do['sigungu']
for dong in sigungu['eup_myeon_dong']
]
return sigungu_codes, dong_codes
return None, None
# 아파트 코드 리스트 가져오기
def get_apt_list(dong_code):
down_url = f'https://new.land.naver.com/api/regions/complexes?cortarNo={dong_code}&realEstateType=APT&order='
header = {
"Accept-Encoding": "gzip",
"Host": "new.land.naver.com",
"Referer": "https://new.land.naver.com/complexes/102378",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0"
}
try:
r = requests.get(down_url, headers=header)
r.encoding = "utf-8-sig"
data = r.json()
if 'complexList' in data and isinstance(data['complexList'], list):
df = pd.DataFrame(data['complexList'])
required_columns = ['complexNo', 'complexName', 'buildYear', 'totalHouseholdCount', 'areaSize', 'price', 'address', 'floor']
for col in required_columns:
if col not in df.columns:
df[col] = None
return df[required_columns]
else:
print(f"No data found for {dong_code}.")
return pd.DataFrame(columns=required_columns)
except Exception as e:
print(f"Error fetching data for {dong_code}: {e}")
return pd.DataFrame(columns=required_columns)
# 아파트 코드로 상세 정보를 가져오는 함수
def get_apt_details(apt_code):
details_url = f'https://fin.land.naver.com/complexes/{apt_code}?tab=complex-info'
header = {
"Accept-Encoding": "gzip",
"Host": "fin.land.naver.com",
"Referer": "https://fin.land.naver.com/",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
}
try:
r = requests.get(details_url, headers=header)
r.encoding = "utf-8-sig"
soup = BeautifulSoup(r.content, 'html.parser')
# 아파트 이름 추출
apt_name_tag = soup.find('span', class_='ComplexSummary_name__vX3IN')
apt_name = apt_name_tag.text.strip() if apt_name_tag else 'Unknown'
# 상세 정보 추출
detail_dict = {'complexNo': apt_code, 'complexName': apt_name}
detail_items = soup.find_all('li', class_='DataList_item__T1hMR')
for item in detail_items:
term = item.find('div', class_='DataList_term__Tks7l').text.strip()
definition = item.find('div', class_='DataList_definition__d9KY1').text.strip()
if term in ['공급면적', '전용면적', '해당면적 세대수', '현관구조', '방/욕실', '위치', '사용승인일', '세대수', '난방', '주차', '전기차 충전시설', '용적률/건폐율', '관리사무소 전화', '건설사']:
detail_dict[term] = definition
return detail_dict
except Exception as e:
print(f"Error fetching details for {apt_code}: {e}")
return {}
# 아파트 정보를 수집하는 함수 (법정동 선택 가능)
def collect_apt_info_for_city(city_name, sigungu_name, dong_name=None, json_path='/content/drive/MyDrive/district.json'):
sigungu_codes, dong_list = get_dong_codes_for_city(city_name, sigungu_name, json_path)
if dong_list is None:
print(f"Error: {city_name} not found in JSON.")
return None
all_apt_data = []
dong_code_name_map = {dong['code']: dong['name'] for dong in dong_list}
# 법정동 선택
if dong_name and dong_name != '전체':
dong_code_name_map = {k: v for k, v in dong_code_name_map.items() if v == dong_name}
for dong_code, dong_name in dong_code_name_map.items():
print(f"Collecting apartment codes for {dong_code} ({dong_name})")
apt_codes = get_apt_list(dong_code)
if not apt_codes.empty:
for _, apt_info in apt_codes.iterrows():
apt_code = apt_info['complexNo']
print(f"Collecting details for {apt_code}")
apt_details = get_apt_details(apt_code)
if apt_details:
apt_details['dong_code'] = dong_code
apt_details['dong_name'] = dong_name
all_apt_data.append(apt_details)
else:
print(f"No apartment codes found for {dong_code}")
if all_apt_data:
final_df = pd.DataFrame(all_apt_data)
final_df['si_do_name'] = city_name
final_df['sigungu_name'] = sigungu_name
final_df['dong_name'] = final_df['dong_name'].apply(lambda x: x)
# 필요한 모든 열을 포함하도록 설정
columns = ['si_do_name', 'sigungu_name', 'dong_name', 'complexNo', 'complexName', '공급면적', '전용면적', '해당면적 세대수', '현관구조', '방/욕실', '위치', '사용승인일', '세대수', '난방', '주차', '전기차 충전시설', '용적률/건폐율', '관리사무소 전화', '건설사']
for col in columns:
if col not in final_df.columns:
final_df[col] = None
final_df = final_df[columns]
return final_df
else:
return pd.DataFrame(columns=['si_do_name', 'sigungu_name', 'dong_name', 'complexNo', 'complexName', '공급면적', '전용면적', '해당면적 세대수', '현관구조', '방/욕실', '위치', '사용승인일', '세대수', '난방', '주차', '전기차 충전시설', '용적률/건폐율', '관리사무소 전화', '건설사'])
# 엑셀 저장 함수
def save_to_excel(df, city_name, sigungu_name):
now = datetime.now().strftime("%Y%m%d_%H%M%S")
file_name = f"{city_name}_{sigungu_name}_{now}.xlsx"
file_path = f'/content/drive/MyDrive/{file_name}'
df.to_excel(file_path, index=False)
print(f"Data saved to {file_path}")
# 사용자 입력 받기
city_name = input("Enter the city or province name: ")
sigungu_name = input(f"Enter the district name in {city_name} (or '전체' for all districts): ")
dong_name = None
if sigungu_name != '전체':
dong_name = input(f"Enter the dong name in {sigungu_name} (or '전체' for all dongs): ")
# 아파트 정보 수집
apt_data = collect_apt_info_for_city(city_name, sigungu_name, dong_name)
if apt_data is not None and not apt_data.empty:
print(apt_data)
save_to_excel(apt_data, city_name, sigungu_name)
else:
print("No data collected.")
ㅁ 오늘 추가된 정보를 보면 아파트의 정보까지 모두 크롤링할 수 있는 것을 확인 할 수 있습니다. 이제 여기에서 각 아파트의 평형별 정보를 추가하는 것과, 평형대별 아파트의 가격을 조회하면 될 것 같습니다. 다음 편에서 소개할게요! 감사합니다.
대전가볼만한곳을 찾는다면 단순히 번화가나 흔한 유원지를 벗어나 지역 고유의 역사적 숨결과 화려한 야경을 동시에 만끽하는…
티빙 개인정보 유출 사태로 피해를 입은 회원은 자동 지급이 아니라 오는 9월 30일까지 직접 홈페이지나…
청도날씨는 유난히 청명하고 선선한 가을바람이 불어오면서 야외 활동을 즐기기에 가장 완벽한 시기에 접어들었습니다. 경북 청도…
2026년 10월축제는 전국 각지에서 다채로운 문화 예술 행사와 함께 화려한 가을의 시작을 알리고 있습니다. 선선한…
정치권에서 직설적인 화법과 강력한 추진력으로 늘 화제의 중심에 서 있는 홍준표 전 대구시장은 검사 시절부터…
2026년 9월축제는 선선한 가을바람과 함께 서울 전역과 전국 각지에서 다채롭게 펼쳐지며 일상의 활력을 불어넣어 주고…