7월 25일
구글 지도 크롤링
구글 지도에서 식당 이름과 구글 별점을 크롤링
해당 글을 읽으면서 진행했습니다.
# selenium의 webdriver를 사용하기 위한 import
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
import csv
# 크롬드라이버 실행
driver = webdriver.Chrome()
# 크롬 드라이버에 url 주소 넣고 실행
driver.get('https://www.google.com/maps')
# 페이지가 완전히 로딩되도록 3초 동안 기다림
time.sleep(3)
# 검색어 창을 찾아 search_box 변수에 저장 (By.ID 방식)
search_box = driver.find_element(By.ID, 'searchboxinput')
search_box.send_keys('마포구 식당')
search_box.send_keys(Keys.RETURN)
time.sleep(3)
# 스크롤을 하면서 더 많은 내용을 로드하고 텍스트를 추출하는 함수
def extract_text_with_scroll(driver, container_xpath, scroll_pause_time=3, max_scrolls=100):
extracted_texts = []
# 검색 결과 컨테이너 요소 찾기
results_container = driver.find_element(By.XPATH, container_xpath)
last_height = driver.execute_script("return arguments[0].scrollHeight", results_container)
for _ in range(max_scrolls):
# 컨테이너 내에서 스크롤
driver.execute_script("arguments[0].scrollTo(0, arguments[0].scrollHeight);", results_container)
# 새로운 내용이 로드되도록 잠시 기다림
time.sleep(scroll_pause_time)
# 새로운 높이를 계산하여 더 이상 스크롤할 내용이 없으면 종료
new_height = driver.execute_script("return arguments[0].scrollHeight", results_container)
if new_height == last_height:
break
last_height = new_height
# 결과 페이지에서 원하는 텍스트를 포함하는 div 요소 찾기
elements = driver.find_elements(By.CLASS_NAME, 'qBF1Pd')
grates = driver.find_elements(By.CLASS_NAME, 'MW4etd')
for n in range(len(elements)):
text = (elements[n].text, grates[n].text)
if text not in extracted_texts:
extracted_texts.append(text)
return extracted_texts
# 검색 결과 컨테이너 이름 설정
container_xpath = '//*[@id="QA0Szd"]/div/div/div[1]/div[2]/div/div[1]/div/div/div[1]/div[1]'
# 텍스트 추출
texts = extract_text_with_scroll(driver, container_xpath)
# 브라우저 종료
driver.quit()
# 추출한 데이터를 CSV 파일로 저장
csv_file = "extracted_data.csv"
with open(csv_file, mode='w', newline='', encoding='utf-8-sig') as file:
writer = csv.writer(file)
writer.writerow(["Name", "GoogleRating"]) # 헤더 작성
writer.writerows(texts)
print(f"Data has been written to {csv_file}")
Python
복사
경로(?)로 CLASS_NAME과 XPATH이 있는데 뭐가 좋은지는 모르겠음.
구글 지도에서 주소를 가져다가 쓸려고 했는데 한 클래스 안에 여러가지가 묶여있어서 애를 먹는중..
식당 이름과 별점 스크래핑은 정상적으로 작동하는데 문제는 중간에 리뷰 없음 식당이 들어가면서 문제가 발생 중.
→아마도 스크래핑 값이 없는듯?
→ 일단 리뷰 없음 식당을 찾아서 F12로 봐야지 수정할 수 있을 것 같은데…
→ 아니면 그냥 전체를 가져와서 따로 데이터를 추출? (CLASS NAME = UaQhfb)
일단 별점 제외하고 만들어본 csv파일 (구글 지도에서 가져온 식당 이름들)
리뷰 없음 이 없으면 정상적으로 나옵니다.
# selenium의 webdriver를 사용하기 위한 import
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
import csv
# 크롬드라이버 실행
driver = webdriver.Chrome()
# 크롬 드라이버에 url 주소 넣고 실행
driver.get('https://www.google.com/maps')
# 페이지가 완전히 로딩되도록 3초 동안 기다림
time.sleep(3)
# 검색어 창을 찾아 search_box 변수에 저장 (By.ID 방식)
search_box = driver.find_element(By.ID, 'searchboxinput')
search_box.send_keys('마포구 식당')
search_box.send_keys(Keys.RETURN)
time.sleep(3)
# 스크롤을 하면서 더 많은 내용을 로드하고 텍스트를 추출하는 함수
def extract_text_with_scroll(driver, container_xpath, block_class, name_class, rating_class, address_xpath, scroll_pause_time=3, max_scrolls=10):
extracted_texts = []
# 검색 결과 컨테이너 요소 찾기
results_container = driver.find_element(By.XPATH, container_xpath)
last_height = driver.execute_script("return arguments[0].scrollHeight", results_container)
for _ in range(max_scrolls):
# 컨테이너 내에서 스크롤
driver.execute_script("arguments[0].scrollTo(0, arguments[0].scrollHeight);", results_container)
# 새로운 내용이 로드되도록 잠시 기다림
time.sleep(scroll_pause_time)
# 새로운 높이를 계산하여 더 이상 스크롤할 내용이 없으면 종료
new_height = driver.execute_script("return arguments[0].scrollHeight", results_container)
if new_height == last_height:
break
last_height = new_height
# 결과 페이지에서 원하는 블록 요소 찾기
blocks = driver.find_elements(By.CLASS_NAME, block_class)
for block in blocks:
try:
name = block.find_element(By.CLASS_NAME, name_class).text
except:
name = 'NULL'
try:
rating = block.find_element(By.CLASS_NAME, rating_class).text
except:
rating = 'NULL'
try:
address = block.find_element(By.XPATH, address_xpath).text
except:
address = 'NULL'
extracted_texts.append((name, rating, address))
return extracted_texts
# 검색 결과 컨테이너 이름 설정
container_xpath = '//*[@id="QA0Szd"]/div/div/div[1]/div[2]/div/div[1]/div/div/div[1]/div[1]'
block_class = 'UaQhfb'
name_class = 'qBF1Pd'
rating_class = 'MW4etd'
# address_class = 'W4Efsd'
address_xpath = '//*[@id="QA0Szd"]/div/div/div[1]/div[2]/div/div[1]/div/div/div[1]/div[1]/div[7]/div/div[2]/div[4]/div[1]/div/div/div[2]/div[4]/div[1]/span[3]/span[2]'
# 텍스트 추출
texts = extract_text_with_scroll(driver, container_xpath, block_class, name_class, rating_class, address_xpath)
# 브라우저 종료
driver.quit()
# 추출한 데이터를 CSV 파일로 저장
csv_file = "extracted_data.csv"
with open(csv_file, mode='w', newline='', encoding='utf-8-sig') as file:
writer = csv.writer(file)
writer.writerow(["Name", "Rating", "address"]) # 헤더 작성
writer.writerows(texts)
print(f"Data has been written to {csv_file}")
Python
복사
Chat GPT의 도움으로 수정된 내용. 주소까지 가져오고 싶은데 주소가 다른 내용들하고 같은 CLASS를 사용합니다… CLASS NAME으로 안돼서 xpath도 해봤는데 NULL만 가져오네요.
→ 구글지도는 포기하고 네이버 지도로 시도하려고 합니다.
7월 26일
카카오 지도 크롤링
# selenium의 webdriver를 사용하기 위한 import
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import pandas as pd
# 페이지 로딩을 기다리는데 사용할 time 모듈 import
import time
# 크롬드라이버 실행
driver = webdriver.Chrome()
# 크롬 드라이버에 url 주소 넣고 실행
driver.get('https://map.kakao.com/')
# 페이지가 완전히 로딩되도록 4초 동안 기다림
time.sleep(4)
# 검색어 창을 찾아 search_box 변수에 저장 (By.ID 방식)
search_box = driver.find_element(By.ID, 'search.keyword.query')
def get_kakao_rating(restaurant_name):
if '마포' in restaurant_name or '홍대' in restaurant_name:
pass
else:
restaurant_name = restaurant_name + ' 마포구'
search_box.send_keys(restaurant_name)
search_box.send_keys(Keys.RETURN)
time.sleep(2)
try:
# 카카오 지도 페이지 구조에 맞는 CLASS 수정
rate = driver.find_element(By.XPATH, '//em[@data-id="scoreNum"]')
rating = rate.text
except:
rating = 'NULL'
try:
address = driver.find_element(By.CLASS_NAME,'addr')
addresses = address.text
except:
addresses = 'NULL'
time.sleep(1)
# 검색어 창 비우기
search_box.clear()
return rating, addresses
# Load the CSV file
file_path = 'extracted_data.csv'
data = pd.read_csv(file_path)
# Kakao Ratings 칼럼 추가
data['KakoRating'] = None
data['Address'] = None
# Iterate over each restaurant and get the Naver rating
for index, row in data.iterrows():
restaurant_name = row['Name']
kakao_rating, addresses = get_kakao_rating(restaurant_name)
data.at[index, 'KakoRating'] = kakao_rating
data.at[index, 'Address'] = addresses
time.sleep(1)
# 데이터 저장
data.to_csv('kakao_test.csv', encoding='utf-8-sig', index=False)
# 브라우저 닫기
driver.quit()
Python
복사
•
구글 지도에서 크롤링한 csv 파일을 이용해서 식당 이름으로 검색하여 카카오 별점 과 가게 주소 를 스크래핑
•
식당 이름으로 검색하다보니 동명의 식당이 여러개 검색되는 경우가 발생해서 식당 이름에 홍대 나 마포 가 없으면 마포구 를 추가하여 검색하도록 설정
카카오 지도 별점과 주소가 추가된 버전
위도 경도 크롤링
# selenium의 webdriver를 사용하기 위한 import
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import pandas as pd
# 페이지 로딩을 기다리는데 사용할 time 모듈 import
import time
# 크롬드라이버 실행
driver = webdriver.Chrome()
# 크롬 드라이버에 url 주소 넣고 실행
driver.get('http://www.moamodu.com/develop/daum_map.php')
# 페이지가 완전히 로딩되도록 4초 동안 기다림
time.sleep(4)
def get_lag_lng(address):
# 검색어 창을 찾아 search_box 변수에 저장 (By.ID 방식)
search_box = driver.find_element(By.ID, 'addr')
# 검색하기 버튼을 찾아 enter_box 변수에 저장
enter_box = driver.find_element(By.CLASS_NAME, 'btn.h22')
# 다른 값이 들어오면 필터링
if type(address) != str:
return '좌표가 검색 되지 않았습니다1', '좌표가 검색되지 않았습니다1'
search = address.split('\n',1)[0]
search_box.send_keys(search)
enter_box.click()
time.sleep(2)
try:
# 위도 경도 찾아서 변수에 넣기
laglng = driver.find_element(By.ID, 'coord')
# 위도, 공백, 경도 분리하여 변수에 지정
lag, _, lng = laglng.text.split('\n')
except:
driver.refresh()
return '좌표가 검색 되지 않았습니다2', '좌표가 검색되지 않았습니다2'
try:
lagtitude = lag.split(':')[1] # 위도 : __._______
except:
lagtitude = 'NULL'
try:
longitude = lng.split(':')[1] # 경도 : __._______
except:
longitude = 'NULL'
time.sleep(1)
# 검색어 창 비우기(새로고침)
driver.refresh()
return lagtitude, longitude
# Load the CSV file
file_path = 'kakao_test.csv'
data = pd.read_csv(file_path)
# 칼럼 추가
data['Latitude'] = None
data['Longitude'] = None
# 식당 주소로 위도 경도 획득 후 입력
for index, row in data.iterrows():
restaurant_address = row['Address']
lagtitude, longitude = get_lag_lng(restaurant_address)
data.at[index, 'Latitude'] = lagtitude
data.at[index, 'Longitude'] = longitude
time.sleep(1)
# 데이터 저장
data.to_csv('kakao_latlng_add.csv', encoding='utf-8-sig', index=False)
# 브라우저 닫기
driver.quit()
Python
복사
누군가 만들어둔 주소를 기반으로 위도, 경도를 찾는 웹페이지를 발견
이를 기반으로 위도 경도가 추가된 csv파일
7월 27일
네이버 평점 크롤링
# selenium의 webdriver를 사용하기 위한 import
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import pandas as pd
# 페이지 로딩을 기다리는데 사용할 time 모듈 import
import time
# 크롬드라이버 실행
driver = webdriver.Chrome()
# 크롬 드라이버에 url 주소 넣고 실행
driver.get('https://map.naver.com/p/')
# 페이지가 완전히 로딩되도록 4초 동안 기다림
time.sleep(4)
def get_naver_rating(restaurant_name):
search_box = driver.find_element(By.CLASS_NAME, 'input_search')
search_box.send_keys(restaurant_name)
search_box.send_keys(Keys.RETURN)
time.sleep(5)
clear_box = driver.find_element(By.CLASS_NAME, 'btn_clear')
restaurant_box = driver.find_element(By.CLASS_NAME, 'ApCpt')
restaurant_box.click()
try:
# 네이버 지도 페이지 구조에 맞는 Xpath 수정
rate = driver.find_element(By.XPATH, '//*[@id="app-root"]/div/div/div/div[2]/div[1]/div[2]/span[1]/span')
rating = rate.text
except:
rating = 'NULL'
time.sleep(1)
# 검색어 창 비우기
clear_box.click()
return rating
# Load the CSV file
# file_path = 'extracted_data.csv'
# data = pd.read_csv(file_path)
# Naver Ratings 칼럼 추가
# data['NaverRating'] = None
# Iterate over each restaurant and get the Naver rating
# for index, row in data.iterrows():
# restaurant_name = row['Name']
# naver_rating = get_naver_rating(restaurant_name)
# data.at[index, 'NaverRating'] = naver_rating
# # Adding a small delay to avoid getting blocked by the server
# time.sleep(1)
# 데이터 저장
# data.to_csv('extracted_data_naver.csv', index=False, encoding='utf-8-sig')
test_rate = get_naver_rating('제순식당 마포구')
print(test_rate)
# 브라우저 닫기
driver.quit()
Python
복사
계속 해보는데 네이버는 도저히 안되겠어서 수작업으로 작업합니다…
7월 28일
네이버 평점까지 추가해서 완료 (수작업..ㅠㅠ)
식당 이미지 스크래핑(구글 이미지)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import pandas as pd
# 페이지 로딩을 기다리는데 사용할 time 모듈 import
import time
# 크롬드라이버 실행
driver = webdriver.Chrome()
# 크롬 드라이버에 url 주소 넣고 실행
driver.get('https://www.google.com/maps')
# 페이지가 완전히 로딩되도록 3초 동안 기다림
time.sleep(3)
# 검색어 창을 찾아 search_box 변수에 저장 (By.ID 방식)
search_box = driver.find_element(By.ID, 'searchboxinput')
def get_kakao_image(restaurant_name):
if '마포' in restaurant_name or '홍대' in restaurant_name:
search_query = restaurant_name
else:
search_query = restaurant_name + ' 마포구'
search_box.send_keys(search_query)
search_box.send_keys(Keys.RETURN)
time.sleep(4)
try:
image_url = driver.find_element(By.XPATH, '//*[@id="QA0Szd"]/div/div/div[1]/div[2]/div/div[1]/div/div/div[1]/div[1]/button/img')
image = image_url.get_attribute('src')
except:
image = 'NULL'
# 검색어 창 비우기
search_box.clear()
return image
# Load the CSV file
file_path = 'final.csv'
data = pd.read_csv(file_path)
# Image 칼럼 추가
data['Image'] = None
# Iterate over each restaurant and get the Google image
for index, row in data.iterrows():
restaurant_name = row['Name']
image = get_kakao_image(restaurant_name)
data.at[index, 'Image'] = image
time.sleep(1)
# 데이터 저장
data.to_csv('Google_image.csv', encoding='utf-8-sig', index=False)
# 브라우저 닫기
driver.quit()
Python
복사
•
코드는 기존에 사용했던 코드들 살짝 수정해서 사용했어요.
•
이미지 url은 .text가 아니라 .get_attribute('src') 을 사용해야 한다고 하네요.
•
이미지 url을 크롤링한 버전입니다 (== 최종버전)