본문 바로가기
코딩∙데이터분석🧑🏻‍💻

[웹크롤링] python selenium beautifulsoup 파싱한 html에 코드가 없을 때 / 데이터가 안나올 때 / 페이지 로딩 대기 / 페이지 대기 / 페이지 조작

by 빕비빅 2022. 11. 28.

역시나... 경데분 과제로 브랜드 하나를 골라서 매장 정보 크롤링하는 걸 하고 있는데,

적당한 사이트를 찾다가 빽다방으로 선택했다. 

대충 이렇게 생김.

개발자 도구로 코드 확인해보니 html 코드도 딱 tbody > tr > td, td, td, ... 교과서 예제랑 거의 비슷하길래 딱이군! 했는데
역시 예제는 예제였던것...! 현실은 교과서처럼 아름답지 않고 -_-

from bs4 import BeautifulSoup
import urllib.request
import pandas as pd
from selenium.webdriver.support.select import Select 

URL = "https://paikdabang.com/store/"

html = urllib.request.urlopen(URL)
soup = BeautifulSoup(html, 'html.parser')

wd = webdriver.Chrome()
wd.get(URL)

soup = BeautifulSoup(wd.page_source, 'html.parser')
print(soup.prettify())
<!-- START LIST -->
<tbody id="store_list">
</tbody>
<!-- END LIST -->

코드 예쁘게 잘 뽑아봤건만 <table><tbody>까지만 나와있고 안이 텅 빈 채로 파싱되는 게 아니겠나...
개발자 도구로 다시 확인해봐도

이렇게 넘나 잘 보이는 <tr>태그들이...! 하나도 파싱되고 있지 않은 거였다.

이런 경우 확인해보니 데이터가 로딩이 안된 상태에서 Html부분을 너무 빠르게 긁어와서(...?대충 내가 이해한 바로는 그랬음)
웹드라이버를 좀 기다리게 해서 요소가 있는지 확인 후 파싱을 해야한다는 것..!

난 html, css만 조금 알아서 웹크롤링.. 아무리 해도 javascript랑 jquery 같은 건 잘 몰라서 맨날 얼레벌레하는 것 같다 흐흑
자바스크립트 공부를 더는 미룰 수는 없는 건가..!!!!

조금 더 소스코드를 읽어보니 빽다방 페이지는 jquery table로 되어있어서
'jquery table +.beautifulsoup + selenium' 키워드로 구글링해 해결할 수 있었당

 

Web Scraping Jquery tables with BeautifulSoup and Selenium

I'm trying to get the data from a table in a site that everyday is updated from this site http://mananciais.sabesp.com.br/HistoricoSistemas?SistemaId=0. I'm learning BeautifulSoup and Selenium and

stackoverflow.com

경데분 과제.. 금방 할 줄 알고 만만하게 생각해서 엄청나게 미뤘더니 왜이렇게 오래걸리나요...? 어쩌면 막힐 때마다 블로그나 써서 그럴 수도...

WebDriverWait() : 웹드라이버 기다리게 하기
visibility_of_element_located() : 요소가 보이는지 확인하기(웹드라이버가 읽을 수 있는지 없는지 기준인 것 같다)

 

그래서 어떻게 하느냐?!

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

 

일단 요놈들을 몽땅 다 가져와준다.

driver = webdriver.Chrome()
site = '내가가져올사이트'
driver.get(site)
WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID,"contentID")))
soup = BeautifulSoup(driver.page_source, 'html.parser')
print(soup.prettify())

WebDriverWait(driver, 10) : driver 10초 기다리게 하기 <- 근데 난 한국인이니까 3초로 줄였다. 된다.

EC.visibility_ofelement_located()에 parameter는 (By.Locator, "locatorValue")인데 
By.ID : ID로 지정하기
By.XPATH : XPath로 지정하기
By.CLASS_NAME : Class 이름으로 지정하기

요정도 있는 것 같다. 이거 3개면 충분히 다 커버칠 것 같아서 더 안찾아봄ㅎ... 

아무튼 그래서 구글이 가르쳐준 대로 

from bs4 import BeautifulSoup
import urllib.request
import pandas as pd
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select 

URL = "https://paikdabang.com/store/"

html = urllib.request.urlopen(URL)
soup = BeautifulSoup(html, 'html.parser')

wd = webdriver.Chrome()
wd.get(URL)

WebDriverWait(wd,3).until(EC.visibility_of_element_located((By.ID,"store_list")))
soup = BeautifulSoup(wd.page_source, 'html.parser')
print(soup.prettify())

아까 는 절대 안보이던 테이블 내용 리스트가 보이기 시작했다! 이제 csv로 옮기기만 하면 된다 얄루

 


찾아보다가 잘못 찾은 구글링 결과지만 내용이 유익해서 다른 문서도 첨부한다.

Selenium Chrome 자동화 페이지 조작 관련 잘 정리된 문서

 

Python + Selenium을 이용하여 chrome 자동화 - 페이지 조작 및 스크린샷 관련 정리

selenium, web driver, google, python, chrome, click, sleep

thesoul214.github.io

기타 BeautifulSoup Error 참고

 

Beautiful Soup - Trouble Shooting

Beautiful Soup - Trouble Shooting Error Handling There are two main kinds of errors that need to be handled in BeautifulSoup. These two errors are not from your script but from the structure of the snippet because the BeautifulSoup API throws an error. The

www.tutorialspoint.com

 

++ visibility_of_element() 보다 presence_of_element()가 더 빠르다! 그리고 잘 작동함(일단 내 코드에서는)
참고 : https://stackoverflow.com/questions/38038920/visibilityofelementlocated-vs-presenceofelementlocated

댓글