selenium Tips
서론
개인 프로젝트 간 셀레니움을 사용한 코드들을 정리한 페이지입니다.
셀레니움
HeadLess(헤드리스) 및 options
driver_options = webdriver.ChromeOptions()
driver_options.add_argument("--mute-audio")
# driver size
driver_options.add_argument('window-size=1920x1080');
driver_options.add_argument('--start-maximized')
# headless
driver_options.headless = True
driver_options.add_argument('--disable-gpu')
# driver user options
driver_options.add_argument(
"user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36")
# driver 옵션 적용 및 실행
driver = webdriver.Chrome(options=driver_options)
driver.get(url)
driver.implicitly_wait(5)
# 스크립트 실행 : 한국어 설정, NVIDIA gpu로 설정
driver.execute_script("Object.defineProperty(navigator, 'plugins', {get: function() {return[1, 2, 3, 4, 5]}})")
driver.execute_script("Object.defineProperty(navigator, 'languages', {get: function() {return ['ko-KR', 'ko']}})")
driver.execute_script(
"const getParameter = WebGLRenderingContext.getParameter;WebGLRenderingContext.prototype.getParameter = function(parameter) {if (parameter === 37445) {return 'NVIDIA Corporation'} if (parameter === 37446) {return 'NVIDIA GeForce GTX 980 Ti OpenGL Engine';}return getParameter(parameter);};")
find_element_by_~~
find_elements_by~~
id, classname, xpath, css_selecter 등 다양한 방법으로 element를 찾을 수 있다
당연한 이야기지만 elements는 요소가 다수일 때, element는 요소가 한 개일 때 사용하자
id 또는 classname 검색할 때 like 검색 방법
/* Internal links, beginning with "#" */
~~으로 시작할때 ^=
a[href^="#"] {
background-color: gold;
}
어디에 있든 *=
/* Links with "example" anywhere in the URL */
a[href*="example"] {
background-color: silver;
}
어디에 있든 대소문자 상관없이
/* Links with "insensitive" anywhere in the URL,
regardless of capitalization */
a[href*="insensitive" i] {
color: cyan;
}
~~로 끝날때 $=
/* Links that end in ".org" */
a[href$=".org"] {
color: red;
}
# 사용했던 예시
result_list = result.find_elements_by_css_selector("[id^=react-autowhatever-1--item-]")
내부 element scroll down
셀레니움 사용간 Infinitiscroll이 적용된 요소가 있어서 Scroll_Down을 반복할 일이 필했었다.
이하 아래는 검색해서 찾고, 적용한 코드이다.
# 스크롤할 내부 요소를 마지막으로 잡고
scroll_element = driver.find_elements_by_class_name('jobdom-post-container')[-1]
# 그 요소까지 스크롤 다운
driver.execute_script("arguments[0].scrollIntoView();", scroll_element);
get_attribute
selenium은 요소의 text 뿐만 아니라 attribute까지 얻을 수 있다.
이하 사용 예시 코드
href = driver.find_elements_by_class_name('btn-post-corpinfo')[1].get_attribute('href')
Screenshot(캡처)
셀레니움의 캡처는 driver의 크기에 비례한다.
그러나 headless가 아닐 시 사용자의 화면에 맞춰질 수 있으므로
headless에서 최대 크기를 조작하여 캡처하는 걸 추천한다.
이하 개인적으로 사용했던 소스코드이다.
element = driver.find_element_by_class_name('company-contents')
total_height = element.size['height'] + 1000
driver.set_window_size(1920, total_height)
time.sleep(1)
screenshot = element.screenshot_as_png
pathlib.Path(path).mkdir(parents=True, exist_ok=True)
with open((path + company_name + "_" + company_code + '_company_review.png'), 'wb') as f:
f.write(screenshot)
element를 한 개 가져와서 height의 길이를 늘려서 screenshot을 하는 걸 볼 수 있다.
기타
class의 이름이 한 칸씩 띄어져 있을 땐 ' . '(점)을 사용하자
driver.find_element_by_class_name('foo.bar')
xpath와 css_selector 같은 경우는 개발자 모드에서 찾아볼 수 있다.
elements 반복
find_elements_by_class_name과 같은 많은 요소들을 찾을 시
for문으로 각 요소를 탐색할 수 있다.
div in div 탐색
예시가 java selenium으로 나와있긴 하지만 비슷하게 사용이 가능하다.
https://stackoverflow.com/questions/30330056/selenium-find-a-child-element-under-a-div
page_source(소스코드)
driver.page_source
로 해당 페이지의 소스코드들을 가져올 수 있다.
특이사항
requests, beautifulsoup로 크롤링 간 데이터가 제대로 안 넘어오는 경우가 종종 있는데
자바스크립트로 페이지 데이터를 조작하는 페이지의 경우엔 안 불러와진다.
그러므로 selenium과 beautifulsoup를 잘 조합하여 크롤링하면 뛰어난 크롤링 기능을 만들 수 있다.