#로우코드10기
유튜브 크롤링 무료 강의를 보다가 한 강사분이 네이버플레이스에서 내가 원하는 업체를 키워드로 검색하여, 순위가 몇 등인지 확인하는 파이썬 프로그램을 가르쳐주셔서 연습해 만들어보았습니다.
기존에는 파이썬 코드 내에 '키워드'와 '업체에 고유로 부여된 'ID'를 미리 입력하여,순위를 확인하는 것이었습니다. 여기에 더 클로드3와 대화하며 응용할 것을 고민했는데요,
더 간편하게 사용하도록 임의로 키워드와 업체 ID를 넣고 스트림릿으로 개량하여, 키워드 기준 전체 업체 순위를 확인하는 프로그램을 만들었습니다.
최종 간단 프로세스는 아래와 같습니다.
1. 네이버 검색창 + 키워드로 드라이버 get (키워드는 마곡곱창, 업체는 조아라황소곱창 마곡나루역점 입니다)
2. 네이버 플레이스 펼쳐서 더보기 탭을 클릭하기
3. 'keyword' 더보기 버튼을 클릭하기
4. 업체 ID를 가지고 스크롤을 내리면서 (광고제외) 해당 업체를 찾기
5-1. 업체를 못 찾을 경우 "쿼리 검색결과로는 순위가 잡히지 않는 업체입니다."
5-2. 업체를 찾을 경우 해당 업체의 순위까지 전체 업체의 리스트와 순위를 <b>해당업체까지 노출하기
클로드와 코딩하면서 해결한 문제는 아래와 같습니다.
먼저, 기존에 '키워드'와 '업체에 고유로 부여된 'ID'를 미리 입력하여,순위를 확인하는 코드를 던져주고, 해당 업체를 찾는 프로세스를 검토했습니다. 문제는 그 사이 네이버 로직이 변경되어, 아래로 스크롤을 무한으로 내리면서 업체를 찾는 과정을 수정해야했습니다. 네이버가 지ral 맞네요..
덕분에 ‘내가 지정한 업체를 찾을떄까지 밑으로 무한 스크롤을 내리는건 완성했습니다.
다음에는 streamlit으로 이를 구현하고, 추가적으로 해당 업체뿐만이 아니라, 이전업체의 리스트까지 나오는 프로그램을 구현해보고싶었습니다.
문제는 업체의 ID를 다시 잘 찾지 못해서, 엘리먼트를 재지정 했어야 했습니다. 그러나 ㅠㅠ 기존에 CSS selector로 찾았지만, 어떻게 순위를 잡아야 할 지 몰라서, 아예 클로드3에게 class NAME을 던져주고 이것만 리스트로 만들어서 순위를 매겨달라고 묘안을 냈습니다.
잘해줍니다 ㅎㅎㅎ
자잘한 문제를 해결하고 스트림릿 프로그램을 완성했습니다. 잘되네요.
import streamlit as st
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import chromedriver_autoinstaller
def get_rank(검색_쿼리, 업체_ID):
chromedriver_autoinstaller.install()
driver = webdriver.Chrome()
# 1. 네이버 검색창 + 키워드로 드라이버 get
검색_링크 = f"https://m.search.naver.com/search.naver?where=m&sm=top_sly.hst&fbm=0&acr=1&ie=utf8&query={검색_쿼리}"
driver.get(검색_링크)
time.sleep(3)
# "펼처서 더보기" 버튼이 로드될 때까지 대기
펼쳐서_더보기_셀렉터 = "#place-main-section-root > div > div.rdX0R.POx9H > div > a"
# 2.펼쳐서 더보기 탭을 클릭하기
try:
펼쳐서_더보기_엘리먼트 = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, 펼쳐서_더보기_셀렉터))
)
print(펼쳐서_더보기_엘리먼트.text)
펼쳐서_더보기_엘리먼트.click()
except:
print(f"{검색_쿼리} 로 펼쳐서 더보기 버튼을 찾을 수 없음")
# [x] Todo 여기서 함수 종료해야함
# "XX 더보기" 버튼이 로드될 때까지 대기
try:
더보기_셀렉터 = "#place-main-section-root > div > div.M7vfr > a"
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 더보기_셀렉터))).click()
except Exception as e:
print(f"더보기 버튼을 찾을 수 없음: {e}")
driver.quit()
return "더보기 버튼을 찾을 수 없음"
time.sleep(3)
# 업체 찾기
전체_엘리먼트들 = []
타겟_업체_인덱스 = -1
# 스크롤을 내리면서 class="UEzoS"인 엘리먼트 찾기
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
엘리먼트들 = driver.find_elements(By.CLASS_NAME, "UEzoS")
for 엘리먼트 in 엘리먼트들:
if "cZnHG" not in 엘리먼트.get_attribute("class"):
전체_엘리먼트들.append(엘리먼트)
if 업체_ID in 엘리먼트.find_element(By.TAG_NAME, "a").get_attribute("href"):
타겟_업체_인덱스 = len(전체_엘리먼트들) - 1
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(3)
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
break
last_height = new_height
if 타겟_업체_인덱스 == -1:
driver.quit()
return "쿼리 검색결과로는 순위가 잡히지 않는 업체입니다."
rank = 타겟_업체_인덱스 + 1
company_name = 전체_엘리먼트들[타겟_업체_인덱스].find_element(By.CLASS_NAME, "place_bluelink").text
result = f"{검색_쿼리} // 현재 {rank}위에 '{company_name}'이(가) 노출되고 있습니다.\n\n순위:\n"
for i, 엘리먼트 in enumerate(전체_엘리먼트들[:타겟_업체_인덱스+1], start=1):
company_name = 엘리먼트.find_element(By.CLASS_NAME, "place_bluelink").text
result += f"{i}. {company_name}\n"
driver.quit()
return result
def main():
st.title("업체 순위 검색")
검색_쿼리 = st.text_input("검색할 키워드를 입력하세요.")
업체_ID = st.text_input("업체 ID를 입력하세요.")
if st.button("검색"):
if 검색_쿼리 and 업체_ID:
result = get_rank(검색_쿼리, 업체_ID)
st.success(result)
else:
st.error("검색 쿼리와 업체 ID를 모두 입력해주세요.")
if __name__ == "__main__":
main()
배운 점
원래 작성한 코드가 있다면 다시 물어보면서 더 개량할 수 있다.
웹 자동화를 할 때, 엘리먼트를 잘 못찾더라도 HTML 페이지나 추측되는 엘리먼트를 주고 알아서 짜달라고 하면 찰떡같이 해준다. 확실히 디테일하게 알려주면 더 잘만들어주긴하네요.
네이버와 같은 포털은 자동화하기 꽤 번거롭다 ㅠㅠ
딜레이 타임이 길어서 오래걸리네요. 아무래도 개인용이라.