<jupyter_start><jupyter_text>직방- 동이름을 입력하면 아파트 매물을 데이터 프레임으로 만들기- robots.txt  1. 웹서비스 분석 : URL 찾기, 크롤링 전략 세우기- 동이름 입력 -> lat, lng(위도, 경도 가져오기)- lat, lng -> geohash : geohash 패키지 설치- geohash -> item ids 가져오기- item ids -> item datas 가져오기 -> 데이터 프레임으로 만들기<jupyter_code>import requests<jupyter_output><empty_output><jupyter_text>1) 동이름 -> 위도 경도 가져오기<jupyter_code>addr = "성수동" # 주소
url = "https://apis.zigbang.com/search?q={}".format(addr)
response = requests.get(url)
data = response.json()["items"][0] # 파싱 # 간단하게 하나의 데이터만 가져오기
lat, lng = data["lat"], data["lng"] # 위도, 경도 데이터<jupyter_output><empty_output><jupyter_text>2) 위도, 경도 -> geohash 데이터 가져오기<jupyter_code># geohash : 위도, 경도 값을 문자로 바꿔주는 패키지 - > pip install geohash2
import geohash2
# precision : 작을수록 큰범위, 클수록 작은범위
geohash = geohash2.encode(lat, lng, precision = 5)
lat, lng, geohash<jupyter_output><empty_output><jupyter_text>3) geohash -> ids 데이터 가져오기<jupyter_code>url = "https://apis.zigbang.com/property/apartments/items?domain=zigbang&geohash={}&q=type=sales%7Cprice=0~-1%7CfloorArea=0~-1".format(geohash)
response = requests.get(url)
datas = response.json()["items"]
ids = [data["itemId"] for data in datas] # 원하는 itemId를 리스트로 만들기
len(data), ids[:3]<jupyter_output><empty_output><jupyter_text>4) ids -> items 데이터 가져오기<jupyter_code>ids_str = str(ids[:200]).replace(" ", "") # 데이터의 공백을 없애준다. # 공백이 있으면 에러가 난다.
# 200개의 데이터만 가져온다 2345개를 다 가져오면 너무 많은 데이터로 오류가 난다.
url = "https://apis.zigbang.com/property/apartments/items?\
vritemIds={ids}&itemIds={ids}&citemIds={ids}".format(ids = ids_str)
response = requests.get(url)
datas = response.json()["items"]
# 데이터 프레임으로 만들기
item_df = pd.DataFrame(datas)
len(item_df.columns)
# pandas option 설정
# 중간에 columns이 끊어져서 보이는것을 해결
pd.options.display.max_columns # 20개 출력
pd.options.display.max_columns = len(item_df.columns) # 39개
item_df.tail(2)
# 원하는 column을 필터링
columns = [
    "itemId", "buildingFloor", "groupedItemFloor", "grossArea", 
    "lat", "lng", "sales", "itemTitle" 
]
item_df = item_df[columns]
item_df.tail(2)
# grossArea 컬럼 분류
item_df["m2"] = item_df["grossArea"].apply(lambda data: data["m2"])
item_df["p2"] = item_df["grossArea"].apply(lambda data: data["p"])
item_df.drop(columns=["grossArea"], inplace = True)
item_df.tail(2)<jupyter_output><empty_output><jupyter_text>함수로 만들기- 동이름 -> 아파트 매물 데이터 프레임이 출력<jupyter_code>def crawling_apt(addr):
    # 동이름 -> 위도, 경도 가져오기
    url = "https://apis.zigbang.com/search?q={}".format(addr)
    response = requests.get(url)
    data = response.json()["items"][0] # 파싱 # 간단하게 하나의 데이터만 가져오기
    lat, lng = data["lat"], data["lng"] # 위도, 경도 데이터
    
    # 위도, 경도 -> geohash 데이터 가져오기
    geohash = geohash2.encode(lat, lng, precision = 5)
    
    # geohash -> ids 데이터 가져오기
    url = "https://apis.zigbang.com/property/apartments/items?domain=zigbang&geohash={}&q=type=sales%7Cprice=0~-1%7CfloorArea=0~-1".format(geohash)
    response = requests.get(url)
    datas = response.json()["items"]
    ids = [data["itemId"] for data in datas]
    
    # ids -> items 매물정보 : 200개씩
    dfs = []
    for idx in range(0, len(ids), 200):
        start, end = idx, idx + 200
        ids_str = str(ids[start:end]).replace(" ", "")
        url = "https://apis.zigbang.com/property/apartments/items?\
vritemIds={ids}&itemIds={ids}&citemIds={ids}".format(ids = ids_str)
        response = requests.get(url)
        datas = response.json()["items"]
        item_df = pd.DataFrame(datas)
        columns = ["itemId", "buildingFloor", "groupedItemFloor", "grossArea", "lat", "lng", "sales", "itemTitle" ]
        item_df = item_df[columns]
        item_df["m2"] = item_df["grossArea"].apply(lambda data: data["m2"])
        item_df["p2"] = item_df["grossArea"].apply(lambda data: data["p"])
        item_df.drop(columns=["grossArea"], inplace = True)
        dfs.append(item_df)
        
    result_df = pd.concat(dfs)
    result_df.reset_index(drop=True, inplace=True)
    return result_df
result = crawling_apt("성수동")
result.tail(2)<jupyter_output><empty_output><jupyter_text>연습<jupyter_code># 도곡동에서 30층 이상되는 아파트에 고층 매물을 찾아서 구매를 할까 고민
items_df = crawling_apt("도곡동")
items_df.tail(2)
items_df.dtypes
# buildingFloor    object
# items_df["buildingFloor"].astype("int") # 에러
items_df = items_df[items_df["buildingFloor"].notnull()] # Na값 제거
items_df.reset_index(drop=True, inplace=True)
items_df.tail(2)
items_df["buildingFloor"] = items_df["buildingFloor"].astype("int")
result_df = items_df[
    (items_df["buildingFloor"] >= 30) &
    (items_df["groupedItemFloor"] == "고층")
]
len(result_df)
np.average(result_df["sales"]) # 평균값 확인<jupyter_output><empty_output><jupyter_text>모듈로 만들기<jupyter_code>%%writefile zigbang.py
import pandas as pd
import requests
import geohash2

def crawling_apt(addr):
    # 동이름 -> 위도, 경도 가져오기
    url = "https://apis.zigbang.com/search?q={}".format(addr)
    response = requests.get(url)
    data = response.json()["items"][0] # 파싱 # 간단하게 하나의 데이터만 가져오기
    lat, lng = data["lat"], data["lng"] # 위도, 경도 데이터
    
    # 위도, 경도 -> geohash 데이터 가져오기
    geohash = geohash2.encode(lat, lng, precision = 5)
    
    # geohash -> ids 데이터 가져오기
    url = "https://apis.zigbang.com/property/apartments/items?domain=zigbang&geohash={}&q=type=sales%7Cprice=0~-1%7CfloorArea=0~-1".format(geohash)
    response = requests.get(url)
    datas = response.json()["items"]
    ids = [data["itemId"] for data in datas]
    
    # ids -> items 매물정보 : 200개씩
    dfs = []
    for idx in range(0, len(ids), 200):
        start, end = idx, idx + 200
        ids_str = str(ids[start:end]).replace(" ", "")
        url = "https://apis.zigbang.com/property/apartments/items?\
vritemIds={ids}&itemIds={ids}&citemIds={ids}".format(ids = ids_str)
        response = requests.get(url)
        datas = response.json()["items"]
        item_df = pd.DataFrame(datas)
        columns = ["itemId", "buildingFloor", "groupedItemFloor", "grossArea", "lat", "lng", "sales", "itemTitle" ]
        item_df = item_df[columns]
        item_df["m2"] = item_df["grossArea"].apply(lambda data: data["m2"])
        item_df["p2"] = item_df["grossArea"].apply(lambda data: data["p"])
        item_df.drop(columns=["grossArea"], inplace = True)
        dfs.append(item_df)
        
    result_df = pd.concat(dfs)
    result_df.reset_index(drop=True, inplace=True)
    return result_df<jupyter_output>Writing zigbang.py
{'fraction_non_alphanumeric': 0.16621856713585323, 'fraction_numerical': 0.014075597026727818, 'mean_word_length': 4.261231281198003, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 52, 'https://': 9, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '655970', 'license': 'MIT', 'n_tokens_mistral': 2904, 'n_tokens_neox': 3145, 'n_words': 470, 'path': 'Crawling/03_requests_3.ipynb', 'repo_name': 'kimchangkyu/TIL', 'size': '6323'}