제목은 거창하지만 불필요하게 단순 반복적인 업무를 줄이기 위해서 셀레니움을 이용해서 원하는 정보를 취합했다.
파이썬 웹 크롤링이라고 하면 많이 사용되는 BeautifulSoup 라이브러리도 존재한다. 하지만 내가 사용할 기능은 검색할 내용을 검색바에 입력 후 출력되는 값을 가져와야 하는데 앞서 언급한 BeautifulSoup으로는 한계가 있어서 Selenium을 사용하게 되었다.
1. Selenium 라이브러리 설치
: pip install selenium
2. 웹 브라우저 제어를 위한 드라이버 설치 (크롬 드라이버 설치)
: https://chromedriver.chromium.org/downloads 로 접속 후 본인이 사용하는 크롬버전 및 운영체제와 동일한 드라이버를 설치해야 한다. 크롬 상단 3개의 점이 있는 버튼을 클릭 후 Help >> About Chrome을 접속하면 아래와 같이 Version 90.0.xxx 형태의 탭이 열린다. 즉, 나는 Version 90을 다운받아야 한다는 것!
이제 Selenium을 사용할 준비가 끝난 셈인데 작성한 코드를 나눠서 살펴보자.
import requests, openpyxl
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
fileName = 'IPAddressHistory.xlsx'
def loadExcelFile(fileName):
wb = openpyxl.load_workbook(fileName)
ws = wb.active
macList = list()
for i in range(1, ws.max_row + 1):
macList.append(ws['A' + str(i)].value)
print('--- Data successfully loaded')
return macList
def saveExcelFile(IP):
wb = openpyxl.load_workbook(fileName)
ws = wb.active
cellNumber = 1
for elem in IP:
ws['B' + str(cellNumber)] = elem
cellNumber += 1
wb.save(fileName)
wb.close()
if __name__ == '__main__':
# 2번에서 받은 chromedriver가 코딩하는 파일과 동일한 경로라면 구체적으로 입력해 줄 필요없음
# driver = webdriver.Chrome()
driver = webdriver.Chrome('C:/Users/Me/AppData/Local/Programs/Python/chromedriver.exe')
login_url = "접속을 위한 주소"
driver.get(login_url)
element = driver.find_element_by_name('username')
element.clear()
element.send_keys('admin')
element = driver.find_element_by_name('password')
element.clear()
element.send_keys('superSecret')
xpath = '/html/body/div[1]/div/div[2]/form/button'
driver.find_element_by_xpath(xpath).click()
mac = loadExcelFile(fileName)
wb = openpyxl.load_workbook(fileName)
ws = wb.active
cellNumber = 1
for elem in mac:
crawling_url = f"login_url/switch-port-map-reporter?mode=history;address={elem};"
driver.get(crawling_url)
xpath = '/html/body/table/tbody/tr[2]/td[6]'
try:
IP_Addr = driver.find_element_by_xpath(xpath).text
except NoSuchElementException:
IP_Addr = "NA"
ws['B' + str(cellNumber)] = IP_Addr
cellNumber += 1
wb.save(fileName)
wb.close()
우선 아래의 세 라인의 코드는
driver = webdriver.Chrome('C:/Users/Me/AppData/Local/Programs/Python/chromedriver.exe')
login_url = "접속을 위한 주소"
driver.get(login_url)
Selenium으로 브라우저를 실행 후 login_url까지 실행하는 과정이다. 이후 find_element_by_name 또는 find_element_by_xpath와 같이 원하는 태그를 통해서 특정 요소를 찾으면 된다.
driver.find_element_by_name('username')
xpath = '/html/body/table/tbody/tr[2]/td[6]'
IP_Addr = driver.find_element_by_xpath(xpath).text
원하는 태그를 찾고싶으면 크롬에서 F12키를 눌러서 개발자 도구를 실행하면 된다. 그리고 아래 왼쪽 그림에서 보여지는 노란색 버튼을 누른 후 홈페이지에서 원하는 부분을 클릭하면 오른쪽 개발자 도구에서 선택된 element (요소)로 바로 이동시켜준다. 그리고 마우스 오른쪽 버튼을 통해서 xpath를 확인할 수 있게된다.
참고로 해당 코드는 로그인을 위해 키입력, 그리고 특정 버튼의 클릭등이 포함되어 있다. BeautifulSoup보다 Selenium의 장점이 이 부분이 아닐까 생각든다.
# username이라고 되어있는 요소를 찾아서
# admin이라는 username을 입력하기
element = driver.find_element_by_name('username')
element.clear()
element.send_keys('admin')
# 로그인 버튼의 요소를 xpath 형태로 받아 해당 버튼 클릭으로 로그인시도
xpath = '/html/body/div[1]/div/div[2]/form/button'
driver.find_element_by_xpath(xpath).click()
xpath를 정적으로 전달해서 해당 element를 찾는 로직으로 코드를 작성했기 때문에 만약 해당 element를 찾지못한 경우 적절한 예외처리 구문이 없다면 에러가 발생하며 프로그램의 동작이 멈추게 된다. 따라서 try-catch 구문을 통해서 적절한 error handling을 할 수 있다. 직관적으로 NoSuchElementException에 대한 정의 후 except 구문에 한줄만 더 추가해주면 element를 찾지 못하더라도 NA라는 문자열을 대신 저장한다.
from selenium.common.exceptions import NoSuchElementException
try:
IP_Addr = driver.find_element_by_xpath(xpath).text
except NoSuchElementException:
IP_Addr = "NA"
'<툴, 프로그램 관련> > [Script]' 카테고리의 다른 글
Outlook에서 Python Script 실행하기 (0) | 2021.03.16 |
---|---|
MAC Address 포맷 변경 크롬 익스텐션 (0) | 2021.02.10 |
AKiPS 활용해보기 (0) | 2021.01.29 |
Infoblox WAPI example (0) | 2020.12.03 |
[CLI Script] VTP domain gathering pexpect module (0) | 2020.06.02 |