TIL - Selenium
๐ย ๊ณต๋ถ ๋ด์ฉ
Selenium?
Selenium
์น ๋ธ๋ผ์ฐ์ ๋ฅผ ์กฐ์ํ ์ ์๋ ์๋ํ ํ๋ ์์ํฌ
WebDriver
์น ๋ธ๋ผ์ฐ์ ์ ์ฐ๋ํ๊ณ ์ ์ดํ๋ ์๋ํ ํ๋ ์์ํฌ
์ค์น ๋ฐฉ๋ฒ
|
|
Selenium ํ์ฉ
import
- Selenium, webdriver ๋ถ๋ฌ์ค๊ธฐ
|
|
driver ์์ฑ ๋ฐ request&response
- Chrome ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ํฌ๋กฌ์ฐฝ์ ์คํ
|
|
.get(url)
์ผ๋ก request ๋ณด๋
|
|
.page_source
๋ก Response HTML ๋ฌธ์ ํ์ธ
|
|
- with-as ๊ตฌ๋ฌธ์ผ๋ก driver ์๋ ์ข
๋ฃ
- ์์ฑํ ์ฝ๋๋ฅผ ์คํํ ํ driver ์ข ๋ฃ๋๋ฉฐ ํฌ๋กฌ ์ฐฝ๋ ๊บผ์ง
|
|
HTML ์์ ์ถ์ถ
- HTML ํน์ ์์ ์ถ์ถ
- .find_element(by, target)
- .find_elements(by, target)
- by : By.ID, BY.TAG_NAME, BY.CLASS_NAME, BY.XPATH …
|
|
- example 1
|
|
example 2
- ์ฐพ์ผ๋ ค๋ ์์๋ฅผ XPath๋ฅผ ํตํด ์ฐพ์ผ๋ ค๋ ๊ฒฝ์ฐ
1 2 3
path = '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]' result = driver.find_element(By.XPATH, path) print(result.text)
- ์ ์ฌํ XPath๋ฅผ ๊ฐ์ง ์ฌ๋ฌ ์์๋ค์ ๊ฐ์ ธ์ค๋ ๊ฒฝ์ฐ
1 2 3 4 5
# ๋ฐ๋ณต๋๋ ๋ถ๋ถ์ ์ ์ธํ๊ณ ๋ณํ๋ ๋ถ๋ถ์ {}๋ก ์ ์ ํ .format() ํ์ฉ path = '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[{}]/div/a/div[2]/p[1]' for i in range(1, 11): result = driver.find_element(By.XPATH, path.format(i)) print(result.text)
Wait and Call
๋์ ์นํ์ด์ง๋ฅผ ์คํฌ๋ํํ๊ธฐ ์ํด ์ผ์ ์๊ฐ์ ๊ธฐ๋ค๋ฆผ(Wait)
Implicit Wait
- .implicitly_wait({num}) : num์ด๋์ ๋ก๋ฉ์ ๊ธฐ๋ค๋ฆฌ๋๋ฐ ๊ทธ ์ ์ ์์ ํ ์๋ต์ด ์ค๋ฉด ๋ค์์ผ๋ก ์งํ
1 2 3 4 5
from selenium.webdriver.support.ui import WebDriverWait driver.get(url) driver.implicitly_wait(10) #10์ด result = driver.find_element(By.XPATH, path)
Explicit Wait
- WebDriverWait()
- until() : ์กฐ๊ฑด์ด ๋ง์กฑ๋ ๋๊น์ง
- until_not() : ์กฐ๊ฑด์ด ๋ง์กฑ๋์ง ์์๋๊น์ง
expected_conditions
(EC) : selenium์ ์ ์๋ ์กฐ๊ฑด๋ค
1 2 3 4 5 6 7
from selenium.webdriver.support import expected_conditions as EC with webdriver.Chrome(service = Service(ChromeDriverManager().install())) as driver: driver.get(url) # XPath ๊ฐ path ์ธ ์์๊ฐ ์กด์ฌํ ๋๊น์ง ์ต๋ 10์ด๋์ ๊ธฐ๋ค๋ฆผ element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, path))) print(element.text)
- WebDriverWait()
Events
๋ง์ฐ์ค ์ด๋ฒคํธ
- ๋ง์ฐ์ค ์์ง์ด๊ธฐ, ๋ง์ฐ์ค ๋๋ฅด๊ธฐ, ๋ง์ฐ์ค ๋ผ๊ธฐ ๋ฑ ์ฌ๋ฌ ์ด๋ฒคํธ๊ฐ ์ผ์ด๋ ์ ์์
- ํน์ ๋ฒํผ์ ์ฐพ์ ํ ํด๋ฆญํ๋ ์ฝ๋
1 2 3 4 5 6 7 8 9 10 11
# ๋ค๋ฅธ import ๊ณผ์ ์ ์๋ต from selenium.webdriver import ActionChains driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) driver.get(url) driver.implicitly_wait(0.5) # class ๋ ๊ฐ ์ด์์ธ ๊ฒฝ์ฐ .์ผ๋ก ์ฐ๊ฒฐํด ๋์์ ์ฐธ์กฐ ๊ฐ๋ฅ # class ์ด๋ฆ์ผ๋ก ๋ฒํผ์ ์ฐพ์ button = driver.find_element(By.CLASS_NAME, 'UtilMenustyle__Link-sc-2sjysx-4.ewJwEL') # ์ฐพ์ ๋ฒํผ์ ๋ง์ฐ์ค๋ก `click`ํ๋ ์ด๋ฒคํธ๋ฅผ ์คํ ActionChains(driver).click(button).perform()
ํค๋ณด๋ ์ด๋ฒคํธ
ํค๋ณด๋ ๋๋ฅด๊ธฐ, ํค๋ณด๋ ๋ผ๊ธฐ ๋ฑ ์ฌ๋ฌ ์ด๋ฒคํธ๊ฐ ์ผ์ด๋ ์ ์์
ํน์ ์ ๋ ฅ์ฐฝ์ ์ฐพ์ ํ ์์์ ์ ๋ ฅํ๋ ์ฝ๋
1 2 3 4 5 6 7
# ๋ค๋ฅธ import ๊ณผ์ ์ ์๋ต from selenium.webdriver import ActionChains, Keys # XPath๋ฅผ ํตํด id ์ ๋ ฅํ๋ input ํ๊ทธ๋ฅผ ์ฐพ์ id_input = driver.find_element(By.XPATH, id_path) # {your_id}๋ฅผ input์ ์ ๋ ฅํ๋ ์ด๋ฒคํธ๋ฅผ ์คํ ActionChains(driver).send_keys_to_element(id_input, {your_id}).perform()
๋ก๊ทธ์ธ ์๋ํ ์์
- ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ด๋ ํ, ์์ด๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํ๊ณ ๋ก๊ทธ์ธ๋ฒํผ์ ๋๋ฅด๋ ์ฝ๋
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
import time # url, id_path, pw_path ๋ฑ์ ์ฌ์ดํธ๋ง๋ค ๋ฌ๋ผ์ง driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) driver.get(url) time.sleep(1) driver.implicitly_wait(0.5) button = driver.find_element(By.CLASS_NAME, {class_name_1}) ActionChains(driver).click(button).perform() time.sleep(1) id_input = driver.find_element(By.XPATH, id_path) ActionChains(driver).send_keys_to_element(id_input, {your_id}).perform() time.sleep(1) pw_input = driver.find_element(By.XPATH, pw_path) ActionChains(driver).send_keys_to_element(pw_input, {your_password}).perform() time.sleep(1) login_button = driver.find_element(By.CLASS_NAME, {class_name_2}) ActionChains(driver).click(login_button).perform()
๐ย CHECK
(์ด๋ ต๊ฑฐ๋ ์๋กญ๊ฒ ์๊ฒ ๋ ๊ฒ ๋ฑ ๋ค์ ํ์ธํ ๊ฒ๋ค)
selenium
- mouse events, keyboard events ์ฐพ์๋ณด๊ธฐ
- EC(expected condition)์ ๋ค๋ฅธ ์กฐ๊ฑด์๋ ์ด๋ค๊ฒ ์๋์ง ์ฐพ์ ์ ๋ฆฌํด๋ณด๊ธฐ
์ฌ๋ฌ class๋ฅผ ๊ฐ์ง ์์ ์ฐพ๊ธฐ
class_name_1.class_name_2
์ฒ๋ผ.
์ผ๋ก ์ฐ๊ฒฐํ์ฌ ๋์์ ์ฐธ์กฐํ ์ ์์
โ ๋๋ ์
์ค๋๋ 2์๊ฐ ๋ฐ ์ ๋์ ๊ฐ์์ ์ค์ต์ ๋ชจ๋ ๋๋๋ค. ๊ณ์ ์ผ์ฐ ๋๋๊ณ ์ฌ์ด ๋ด์ฉ๋ง ๋์ค๋๊น ๋๋ฌด ๊ฒํฅ๊ธฐ๋ก๋ง ๋ฐฐ์ฐ๋ ๊ฒ ๊ฐ๊ณ , ํผ์์ ๋ ๊ณต๋ถํด์ผํ ๊น ๋ถ์๊ฐ๋ ์กฐ๊ธ ๋ค์๋ค. ๊ทธ๋์ ์ค๋์ TIL์ ์ ์ ๋ค์ ๋ฐฐ์ด๊ฒ๋ค์ ํ์ฉํด KBO์ฌ์ดํธ์์ ์คํฏ์ ์ถ์ถํด๋ณด๋ ค๊ณ ํ๋ค. ๋ค ์งํํ๊ณ ๋์ ๋ฐ๋ก ์ ๋ฆฌํ๊ณ ๊ธ์ ์จ์ ์ฌ๋ฆด ์์ ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ์ด์ ๋ธ๋ก๊ทธ๋ฅผ ์ธํ
ํ ์ดํ์ ๊ธฐ์กด์ TIL์ ์ฌ๋ฆฌ๋ velog
๋ฅผ ์ด๋ป๊ฒ ํด์ผํ ์ง๋ ๊ณ ๋ฏผํ๊ณ ์๋ค. ๋ค ์ง์ฐ๊ธฐ๋ ์๊น๊ณ ๋ ์์ฌ๋ฆฌ์๋ ๋ฉ์ถฐ์ ธ์๋ ๋ธ๋ก๊ทธ ๊ฐ์์..
๋ฐฑ์
์ฉ์ผ๋ก ์ฃผ๋ง์ ๋ชฐ์์ ์ผ์ฃผ์ผ์น๋ฅผ ์ฌ๋ฆฌ๋ ๋ฐฉ๋ฒ๋ ๊ณ ๋ฏผ์ค์ด๋ค!
์์ง ์ ๋ฐ์ ์ผ๋ก ์ฌ์ดํธ์ด๊ธฐ๋ ํ์ง๋ง, ์ ์ ๋ ํฅ๋ฏธ๋ก์์ง๊ณ ์๋ค. ์ดํ์ ๋ฐฐ์ธ ๋ด์ฉ๋ค๊ณผ ๋ค์๋ฌ ์ด์ ํ๊ฒ ๋ ํ๋ก์ ํธ๊ฐ ๊ธฐ๋๋๋ค. ๐ค