☠️ TroubleShooting
네이버 플레이스 크롤링시 404 Not Found 발생 현상
kyuu_ng
2023. 2. 12. 01:10
문제 사항
- 셀레니움을 이용한 크롤링 시 특정 건수에서 404 Not Found 발생하며 웹 접근 차단 되는 현상
- 1000건의 음식점 정보에 대해 크롤링 한다고 가정했을 때 대략적으로 700~800건 사이에서 일시적으로 아래와 같이 오류가 뜨며 차단되는 현상이 있음 ( Not Found로 일시적으로 화면이 Block되면 정보 크롤링이 불가능하고, 약 100~300건을 크롤링 할 동안 아래 페이지가 뜨다가 다시 정상적으로 보여짐 ) ( Not Found가 발생하는 시점은 불특정하며, 주피터노트북을 켜고 있는 Pc가 아닌 다른 Pc에서 해당 URL접속 시 이상 없음 == url 문제는 아닌 것으로 보임)
원인
- 추측 원인 : 셀레니움을 통합 반복적인 웹 접속 시 컴퓨터로 판단하여 크롬 브라우저에서 차단
- 판단 사유 :
- Not Found가 발생하는 시점에 크롤링하고 있는 Url 자체에는 문제가 없음을 다른 pc를 통해서 확인
시도한 방법
- 구글 검색 시 User-Agent 정보를 헤더에 넣어서 같이 보내면 차단 현상이 개선된다는 글이 있어 적용하였으나 증상 동일
- headless 옵션을 사용하여 보낼시에도 현상이 개선된다는 글이 있어 추가 하였으나 증상 동일
- Not Found 오류가 발생하여도 무시하고 그냥 진행
- 이 경우 1000건 중 Not Found가 발생한 시점의 크롤링 건 수 (100~200건)들의 데이터 크롤링 실패
- 20% 데이터 유실 발생
질의사항
- 저희조의 경우 공공API 포탈에서 제공하는 음식점 리스트를 받아서 폐업된 음식점을 제외한 현 영업중인 음식점 리스트를 엑셀로 만들어서 네이버 지도에 ‘음식점 이름’을 키워드로 검색한 결과를 크롤링 하게끔 구성하였습니다.
- ( 음식점 리스트 엑셀 → 가게 이름으로 네이버 지도 검색 → Url 획득하여 Url에 있는 블로그 리뷰 획득 )
- 크롤링은 python, 셀레니움을 이용하였고 문제가 발생하는 코드는 아래의 부분으로 ‘음식점 이름’을 키워드로 검색한 결과를 크롤링 하게끔 동작하는 부분입니다.
- 구글링시 반복적인 작업으로 인한 브라우저 차단 시 User-agent/headless 옵션을 통해 해결이 가능하다고 작성되어 있으나, 해결되지 않아 글을 작성드립니다.
- 이 방법 외 해결방안이나, 데이터를 수집하는 방법 중 다른 걸 시도해볼 부분이 있을 지 문의드리고싶습니다. (만약 현재 상황으로 Not Found가 나지 않게 하려면 음식점 데이터를 500건씩 잘라서 해야하는데 비효율 적인 것 같습니다. 🥺 )
Python 크롤링 코드
# 포스팅 작성 당시 크롬 버젼 : 92
options = webdriver.ChromeOptions()
options.add_argument('headless'). # headless 옵션 사용
options.add_argument("disable-gpu") # 가속 사용 x
options.add_argument("lang=ko_KR") # 가짜 플러그인 탑재
options.add_argument('user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Whale/3.18.154.8 Safari/537.36')
# 네이버 지도 검색창에 [~동 @@식당]으로 검색해 정확도를 높여야 합니다. 검색어를 미리 설정해줍시다.
#df['naver_keyword'] = df['dong'] + "%20" + df['name'] # "%20"는 띄어쓰기를 의미합니다.
df['naver_map_url'] = ''
# 본격적으로 가게 상세페이지의 URL을 가져옵시다
for i, keyword in enumerate(df['placename'].tolist()):
print("이번에 찾을 키워드 :", i, f"/ {df.shape[0] -1} 행", keyword)
try
naver_map_search_url = f"<https://m.map.naver.com/search2/search.naver?query={keyword}&sm=hty&style=v5>"
print(naver_map_search_url)
driver.get(naver_map_search_url)
time.sleep(3.5)
df.iloc[i,-1] = driver.find_element(By.CSS_SELECTOR, "#ct > div.search_listview._content._ctList > ul > li:nth-child(1) > div.item_info > a.a_item.a_item_distance._linkSiteview").get_attribute('data-cid')
# 네이버 지도 시스템은 data-cid에 url 파라미터를 저장해두고 있었습니다.
# data-cid 번호를 뽑아두었다가 기본 url 템플릿에 넣어 최종적인 url을 완성하면 됩니다.
#만약 검색 결과가 없다면?
except Exception as e1:
if "li:nth-child(1)" in str(e1): # -> "child(1)이 없던데요?"
try:
df.iloc[i,-1] = driver.find_element(By.CSS_SELECTOR, "#ct > div.search_listview._content._ctList > ul > li:nth-child(1) > div.item_info > a.a_item.a_item_distance._linkSiteview").get_attribute('data-cid')
time.sleep(1)
except Exception as e2:
print(e2)
time.sleep(1)
else:
pass
driver.quit()
# 이때 수집한 것은 완전한 URL이 아니라 URL에 들어갈 ID (data-cid 라는 코드명으로 저장된) 이므로, 온전한 URL로 만들어줍니다
df['naver_map_url'] = "<https://m.place.naver.com/restaurant/>" + df['naver_map_url']
# URL이 수집되지 않은 데이터는 제거합니다.
df = df.loc[~df['naver_map_url'].isnull()]
해결방안
멘토님의 조언을 듣고 브라우저에 Not Found 오류가 발생하고 페이지가 Block되는 기준을 측정해보았다.
약 500 ~ 700회 사이에서 불규칙하게 Not Found 오류가 발생하였고, 약 20분~30분 사이에 Block이 해제되는 것을 알 수 있었다.
Block되는 패턴이 일정하지않아서 어느 기준까지 조회하게 한 후 잠시 대기할지에 대해서 고민을 하였는데
1차시도는 3번의 테스트 중 중간정도의 기준으로 테스트를 시도했다.
1차 시도
case1) 발생 시점(600회)에서 약 10분간 대기
if i != 0 and i % 600 == 0: // 0번째가 아니거나, 600번째 마다 반복
time.sleep(600) // 10분(60초 * 10)간 대기
결과 : 767회에서 Block이 발생하였으나, Block 해제 시간이 적용전보다 감소됨 ( 적용 전 : 약 20분 , 적용 후 : 약 5분) → Not Found 오류로 인한 크롤링 데이터 손실율 약 20 % → 10 %
💡 Block이 발생하긴 하였으나 Sleep 적용 후 Block 해제 되는 시간이 1/4로 감소됨!
2차 시도
case2) 발생 시점(500회)에서 약 20분간 대기
- 두번째는 3회의 테스트 중 가장 빨리 발생된 횟수(591회)를 기준으로 평균 해제시간만큼 대기하도록 설정
if i != 0 and i % 500 == 0: // 0번째가 아니거나, 500번째 마다 반복
time.sleep(1200) // 20분(60초 * 20)간 대기
결과 : 1000건 ~ 3000건이 포함된 데이터로 크롤링 시도시 Not Found 오류는 한번도 발생되지 않았음!!!!!
→ Not Found 오류로 인한 크롤링 데이터 손실율 20% → 0%
💡 알게된 점 :
- API가 아닌 웹 크롤링시에도 무분별한 요청은 서비스에 부하를 줄 수 있어 이러한 처리를 해두었을 수도 있기 때문에 크롤링시에는 이러한 부분들을 잘 확인해보고 안정적으로 크롤링 할 수 있는 방법을 파악하는 부분이 필요함!.