개발 일기

selenium Tips

친구들안녕 2021. 7. 8. 17:27

서론

개인 프로젝트 간 셀레니움을 사용한 코드들을 정리한 페이지입니다.

 

 

 

셀레니움

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를 잘 조합하여 크롤링하면 뛰어난 크롤링 기능을 만들 수 있다.