2022. 9. 28. 14:26ㆍAI/프로그래머스 AI 코스
웹페이지의 구분
동적 : HTML이 갱신됨(SNS), request후 렌더링시간이 걸린다
정적 : HTML(일반적인 웹사이트)이 고정되어있음
동적 웹사이트의 동작방식
동기처리 : 랜더링을 마친후 데이터를 처리함
비동기처리 : 랜더링이 마칠때까지 기다리지 않고 즉시 데이터 처리를 시작하는 방식으로, 랜더링을 마치기전에 웹스크래핑을 하는경우 일부 데이터를 잃어버릴수 있다.
* 비동기처리방식은 랜더링 시간을 기다릴 필요가 없이 데이터 처리가 이루어지므로 일반적으로는 효율적인 방식이다. 다만, 웹 스크래핑을 하는경우에는 비동기처리 방식에 대해서는 추가적인 조치가 필요하다
동적 웹사이트 스크래핑
1. 비동기 처리방식에서 랜더링을 마친후 데이터처리를 하기위해 데이터 처리전에 적당히 시간을 지연시킨다
2. 웹브라우저가 랜더링을 마치기를 기다리는 방법이 아닌 웹브라우저를 조작해서 데이터를 처리한다 -> Selenium
Install, Import - colab에서 사용시 chorme brower 추가 설치
!pip install selenium
!pip install webdriver-manager
!apt-get update
!apt install chromium-chromedriver #chrome 설치
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
with-as 로 사용
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
# colab 사용시
with webdriver.Chrome('chromedriver', chrome_options=chrome_options) as driver:
driver.get('http://www.example.com')
print(driver.page_source)
# local 사용시
with webdriver.Chrome(service = Service(ChromeDriverManager().install()),\
chrome_options=chrome_options) as driver:
find_element, find_elements & By 조건
driver.find_element(By.XPATH, '//button[text()="Some text"]')
driver.find_element(By.XPATH, '//button')
driver.find_element(By.ID, 'loginForm')
driver.find_element(By.LINK_TEXT, 'Continue')
driver.find_element(By.PARTIAL_LINK_TEXT, 'Conti')
driver.find_element(By.NAME, 'username')
driver.find_element(By.TAG_NAME, 'h1')
driver.find_element(By.CLASS_NAME, 'content')
driver.find_element(By.CSS_SELECTOR, 'p.content')
driver.find_elements(By.ID, 'loginForm')
driver.find_elements(By.CLASS_NAME, 'content')
https://velog.io/@tkjung/Element-%EC%B0%BE%EB%8A%94-%EB%B0%A9%EB%B2%95
Element 찾는 방법
Element를 찾는 다양한 방법에 대해 소개한다
velog.io
with webdriver.Chrome('chromedriver', chrome_options=chrome_options) as driver:
driver.get('http://www.example.com')
content = driver.find_element(By.TAG_NAME, 'p')
print(content.text) # find_element , 'p' Tag의 text
for element in driver.find_elements(By.TAG_NAME, 'p'): # find_elements
print(element.text)
# find_element
This domain is for use in illustrative examples in documents.
You may use this domain in literature without prior coordination or asking for permission.
# find_elements
This domain is for use in illustrative examples in documents.
You may use this domain in literature without prior coordination or asking for permission.
More information...
Example Domain
Example Domain This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission. More information...
example.com
Wait & Call
implict wait : wait time을 지정하여 특정 동작을 기다림
explicit wait : 특정 동작을 기다림
XPath
XML에서 상대 path를 의미.
Xpath = '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]'
Wait 없는경우
with webdriver.Chrome('chromedriver', chrome_options=chrome_options) as driver:
driver.get('https://indistreet.com/live?sortOption=startDate%3ADESC')
Xpath = '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]'
driver.find_element(By.XPATH, Xpath)
* exception 발생 : 비동기 방식이 적용되어어서, 랜더링을 마치기전에 데이터 처리를 요청하면 오류가 발생함
- > wait를 추가해야함
Wait 추가 - implicitly_wait(), // until(), until_not()
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
with webdriver.Chrome('chromedriver', chrome_options=chrome_options) as driver:
driver.get('https://indistreet.com/live?sortOption=startDate%3ADESC')
Xpath = '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]'
# Implicitly wait
driver.implicitly_wait(10)
content = driver.find_element(By.XPATH, Xpath)
# Explicitly wait
content = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, Xpath)))
print(content.text)
여러 Tag 스크래핑
for i in range(1,11):
content = WebDriverWait(driver, 10).\
until(EC.presence_of_element_located(\
(By.XPATH, '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[%d]/div/a/div[2]/p[1]' %i)))
print(content.text)
마우스 이벤트 처리
move, press down, press up...
from selenium.webdriver import ActionChains
driver = webdriver.Chrome('chromedriver', chrome_options=chrome_options)
driver.get('https://indistreet.com/live?sortOption=startDate%3ADESC')
Xpath = '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]'
content = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, Xpath)))
print(content.text) # THREE PUNK MANIACS TOUR
# button 누른후 변경된 내용 출력
Bpath = '//*[@id="__next"]/div/main/div[2]/div/div[2]/div[2]/button[1]'
button = driver.find_element(By.CLASS_NAME, 'chakra-button.css-1esxv66')
ActionChains(driver).click(button).perform()
content = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, Xpath)))
print(content.text) # Sign up
키보드 이벤트
with webdriver.Chrome('chromedriver', chrome_options=chrome_options) as driver:
driver.get('https://hashcode.co.kr/')
time.sleep(1)
button = driver.find_element(By.CLASS_NAME, 'nav-link.nav-signin')
ActionChains(driver).click(button).perform()
id_input = driver.find_element(By.XPATH, '//*[@id="main-app-account"]/div/div[2]/div/div[2]/div[1]/div/div[2]/div[2]/input')
print(id_input.text)
ActionChains(driver).send_keys_to_element(id_input, 'ID').perform() # 키 입력
pw_input = driver.find_element(By.CLASS_NAME, 'FymRFM681OjzOdzor5nk')
ActionChains(driver).send_keys_to_element(pw_input, 'PW').perform() # 키 입력
print(pw_input.text)
button = driver.find_element(By.CLASS_NAME, 'itAWTII94uCyf9uUgREi')
ActionChains(driver).click(button).perform()
Selenium Doc
https://www.selenium.dev/documentation/webdriver/actions_api/
'AI > 프로그래머스 AI 코스' 카테고리의 다른 글
Flask (0) | 2022.10.13 |
---|---|
Git 요약 (0) | 2022.10.04 |
MySQL (0) | 2022.09.28 |
BeautifulSoup4 (0) | 2022.09.27 |
HTTP (1) | 2022.09.26 |