목차
Selenium으로 인식되지 않는 text를 print 하는 방법
동적 테이블 값을 Selenium + BeautifulSoup4 로 출력하는 방법
01. Selenium으로 인식되지 않는 text를 print 하는 방법
나는 이전동안, Selenium을 이용한 동적 사이트 테이블을 크롤링하는 작업을 수행했다.
수행 기록은 아래와 같다.
https://eng-sohee.tistory.com/78
그런데 이걸 하면서, 위 포스팅에 작성되어있듯 문제가 발생했다.
바로, Selenium에서 특정 id 내 text 값이 불러와지지 않는다는 것이다...
노랗게 색칠한 부분을 보면, 똑같이 'find_element_by_id'로 데이터를 가져왔는데도 특정 id는 인식이 안되어 데이터를 못 불러오는 것을 알 수 있다....
class와 구조가 동일한데 왜 12번째 id부터는 인식이 안 되는 걸까...? 답답했다. 😵💦
이 문제를 해결하기 위해 이것저것 시도해봤다. 실패한 기록은 다음과 같다.
- find_element_by_id('아이디명').text
- find_element_by_id('아이디명')
- find_element_by_class_name('클래스명')
- find_elements_by_class_name('클래스명') + list 반환 위해 for loop
- find_element_by_xpath('정적 xpath 경로')
- find_element_by_xpath('동적 xpath 경로')
- table, tbody, tr 경로를 별도로 설정하고 경로 내 모든 td를 출력하도록 for loop
- 등등 많은 잡(?)시도.....
실패 결과는 모두 어떻게 나왔는가?
(1) 공백
(2) None 출력
(3) [<selenium.webdriver.remote.webelement.Web85915d49d36b6db4d7f54d01fe", element="aa107841-78d")>]
그래서 계속 실패를 반복하다가, (여기가 이제 포스팅의 결론) 해결방법을 찾았다!
바로 BeautifulSoup4 + Selenium 을 함께 사용하는 것.
원래도 이 방법을 처음에 썼었지만, 코드가 복잡해지는 것 같아 Selenium으로 모두 하려고 했는데, 실패했다.
따라서 밑져봤자 본전이라고, Selenium을 통해 동적 페이지를 불러 와서, BeautifulSoup4로 특정 값을 뽑아 오는 것을 재시도해봤다.
코드 시도 결과는 아래와 같다.
와 실화인가!!!!! 진짜 실화인가!!!!!! 데이터가 들어온다!!!! 몇 일을 시도했는데.. 이렇게 가까이에 해결 방법이 있었다니 허탈했지만, 이것 저것 삽질한 끝에 해결할 수 있어서 너무 기뻤다 !!! (사실 지금도 기쁘다.)
🔥 오늘의 배운 점
Selenium 으로 데이터값이 정상적으로 print 되지 않으면, BeautifulSoup4를 이용해 값을 출력하도록 하자.
이제, 동적 테이블을 반복적으로 스크롤 다운해가며, BeautifulSoup4로 데이터를 print할 수 있도록 수정해보겠다.
02. 동적 테이블 값을 Selenium + BeautifulSoup4 로 출력하는 방법
중복이 되어도 딕셔너리는 단일키만 들어가기 때문에 괜찮다. 즉 멱등하게 처리할 수 있다. 따라서 딕셔너리형태로 바꿔주었다.
# 마지막 페이지 테이블 데이터 집계
def tail_value():
for i in range(0,22):
save_value = {}
try:
for k in range(0,1):
value = soup.select_one('#mf_tacMain_contents_M1554_body_grpSrchList_cell_{}_{} > nobr'.format(i, k)).text
save_value.setdefault('key_{}'.format(k), value)
# print(save_value)
save_dict['n_{}_{}'.format(datetime.datetime.now().strftime("%Y%m%d"), save_value['key_0'])] = save_value
except AttributeError:
break
# 데이터 수집
for _ in range(0,10000):
btn.send_keys(Keys.DOWN)
save_value = {}
for k in range(0,22):
# 해당 페이지의 전체 html 소스를 string 형태로 답기 위해 html 저장 + 스크롤 다운한 화면을 동적화
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
value = soup.select_one('#mf_tacMain_contents_M1554_body_grpSrchList_cell_{}_{} > nobr'.format(0, k)).text
# 키값이 없으면 키값에 0을 넣고 만약 있으면 키값을 반환
save_value.setdefault('key_{}'.format(k), value)
# print(value)
print(save_dict)
if 'n_{}_{}'.format(datetime.datetime.now().strftime("%Y%m%d"), save_value['key_0']) in save_dict:
cnt += 1
if cnt > 15:
tail_value()
break
save_dict['n_{}_{}'.format(datetime.datetime.now().strftime("%Y%m%d"), save_value['key_0'])] = save_value
'개인(팀) 프로젝트 > 해상물류 통합 데이터 플랫폼 프로젝트' 카테고리의 다른 글
데이터베이스에 csv 파일 업로드 시 에러(value too long for type character) 해결 (0) | 2021.08.01 |
---|---|
08. PSST 기반 사업계획서 작성 방법 (0) | 2021.07.01 |
07. Selenium - 동적 사이트 테이블 Crawling (0) | 2021.06.28 |
05. 데이터 엔지니어링 - 수집 요구사항 및 수집 파이프라인 정의 (0) | 2021.06.14 |
01. 문제 및 요구사항 정의, 와이어 프레임 설계 (0) | 2021.06.01 |