[Python] Selenium
동적으로 웹 페이지에서 어떤 동작들을 하고 싶을때 Python 프로그램을 통해서 또한 가능하다. 아래 코드는 특정 사이트에서 로그인을 하는 프로그램이다.
from selenium import webdriver driver = webdriver.Chrome("chromedriver") driver.implicitly_wait(3) driver.get("https://www.danawa.com/") login = driver.find_element_by_css_selector('li.my_page_service > a') print("HTML 요소: ", login) print("태그 이름: ", login.tag_name) print("문자열: ", login.text) print("href 속성: ", login.get_attribute('href')) login.click() driver.implicitly_wait(3) my_id = "----- 아이디 입력 -----" my_pw = "----- 비밀번호 입력 -----" driver.find_element_by_id('danawa-member-login-input-id').send_keys(my_id) driver.implicitly_wait(2) driver.find_element_by_name('password').send_keys(my_pw) driver.implicitly_wait(2) driver.find_element_by_css_selector('button.btn_login').click()
HTML 요소: 태그 이름: a 문자열: 로그인 href 속성: https://auth.danawa.com/login?url=http%3A%2F%2Fwww.danawa.com%2F |
위 코드의 결과를 보기전에 반드시 chromedriver가 필요하기 때문에 크롬 드라이버를 현재 크롬 버전에 맞춰서 다운받아서 해당 코드와 같은 directory에 저장을 시키면 된다. 그리고 본인의 아이디와 비밀번호도 함께 입력해주면 된다.
위 코드에서 login 변수에서 find_element_by_css_selector('li.my_page_service > a')
는 실제 다나와 사이트에서 로그인 클릭을 나타내는 tag를 가리킨다. 'li.my_page_service > a'
정보는 다나와 사이트에서 우클릭 하여 ‘검사’ 버튼을 누르면 각 region별로 tag를 가리키게 된다.
원하는 tag에서 우클릭 – Copy – Copy selector를 클릭하면 tag 정보가 나오는데 우리가 실제 필요한 부분만 넣으면 된다.
danawa_header > div.danawa_top_search > div > div.my_service > div.my_service_list > ul > li.my_page_service > a > span
[대충 ‘검사’ 클릭 후 보여지는 화면…]login.click()
을 하게되면 클릭하고 난 다음 화면으로 넘어가게 된다.
그리고 아이디와 비밀번호를 입력하기 위해 동일하게 tag 정보를 얻은 뒤 send_keys()
를 통해 아이디와 비밀번호를 전달하고 확인 버튼을 누르면 우리가 원하는 로그인이 된다.
특정 정보 리스트 추출
로그인 후 관심있는 정보들을 리스트로 또한 얻을 수 있다. 정보를 얻는건 selenium을 통해서 얻고 html 정보를 얻으면 그 뒤엔 BeautifulSoup을 통해서 원하는 정보를 parsing하는 코드다.
from selenium import webdriver driver = webdriver.Chrome("chromedriver") driver.implicitly_wait(3) driver.get("https://www.danawa.com/") login = driver.find_element_by_css_selector('li.my_page_service > a') login.click() driver.implicitly_wait(3) my_id = "----본인 아이디 입력하세요----" my_pw = "----본인 패스워드 입력하세요----" driver.find_element_by_id('danawa-member-login-input-id').send_keys(my_id) driver.implicitly_wait(2) driver.find_element_by_name('password').send_keys(my_pw) driver.implicitly_wait(2) driver.find_element_by_css_selector('button.btn_login').click() driver.implicitly_wait(2) wishlist = driver.find_element_by_css_selector('li.interest_goods_service > a').click() driver.implicitly_wait(2) html_src = driver.page_source # html source driver.close() #print(html_src[:]) from bs4 import BeautifulSoup import re soup = BeautifulSoup(html_src, 'html.parser') wish_table = soup.select('table[class="tbl wish_tbl"]')[0] wish_items = wish_table.select('tbody tr') for item in wish_items: title = item.find('div', {'class':'tit'}).text price = item.find('span', {'class':'price'}).text link = item.find('a', href=re.compile('prod.danawa.com/info/')).get('href') print(title) print(price) print(link) print("\n")
Western Digital WD BLUE SN550 M.2 NVMe (500GB) 87,600원 http://prod.danawa.com/info/?pcode=10120452 삼성전자 860 EVO (500GB) 101,100원 http://prod.danawa.com/info/?pcode=5834210 |
웹 페이지에서 파일 다운로드
from selenium import webdriver import time def download_bok_statistics(): driver = webdriver.Chrome("chromedriver") driver.implicitly_wait(3) driver.get("http://ecos.bok.or.kr/jsp/vis/keystat/#/key") excel_download = driver.find_element_by_css_selector('img[alt="download"]') driver.implicitly_wait(3) excel_download.click() time.sleep(5) driver.close() print("파일 다운로드 실행...") return None download_bok_statistics()
파일 다운로드 실행… |
활용 예제
Selenium과 BeautifulSoup을 활용해 특정 키워드를 통해서 우리가 원하는 정보를 찾아내 데이터를 추출하는 프로그램을 아래와 같이 작성할 수 있다.
from selenium import webdriver from bs4 import BeautifulSoup import time def download_bok_statistics_by_keyword(): item_found = 0 while not item_found: keyword = "" while len(keyword) == 0: keyword = str(input("검색할 항목을 입력하세요: ")) driver = webdriver.Chrome("chromedriver") driver.implicitly_wait(3) driver.get("http://ecos.bok.or.kr/jsp/vis/keystat/#/key") time.sleep(5) items1 = driver.find_elements_by_css_selector('a[class="ng-binding"]') items2 = driver.find_elements_by_css_selector('a[class="a-c1-list ng-binding"]') items3 = driver.find_elements_by_css_selector('a[class="a-c4-list ng-binding"]') driver.implicitly_wait(3) items = items1[1:] + items2 + items3 for idx, item in enumerate(items): if keyword in item.text: print("검색어 '%s'에 매칭되는 '%s' 통계지표를 검색 중..." % (keyword, item.text)) item.click() item_found = 1 time.sleep(5) break elif idx == (len(items) - 1): print("검색어 '%s'에 대한 통계지표가 존재하지 않습니다..." % keyword) driver.close() continue else: pass # Get html data html_src = driver.page_source soup = BeautifulSoup(html_src, 'html.parser') driver.close() table_items = soup.find_all('td', {'class':'ng-binding'}) date = [t.text for i, t in enumerate(table_items) if i % 3 == 0] value = [t.text for i, t in enumerate(table_items) if i % 3 == 1] change = [t.text for i, t in enumerate(table_items) if i % 3 == 2] result_file = open('bok_statistics_%s.csv' % keyword, 'w') for i in range(len(date)): result_file.write("%s, %s, %s" % (date[i], value[i], change[i])) result_file.write('\n') result_file.close() print("키워드 '%s'에 대한 통계지표를 저장하였습니다." % keyword) return date, value, change result = download_bok_statistics_by_keyword() print(result)
검색할 항목을 입력하세요: CD 검색어 ‘CD’에 매칭되는 ‘CD수익률(91일) (‘20.05.29)’ 통계지표를 검색 중… 키워드 ‘CD’에 대한 통계지표를 저장하였습니다. ([‘2013’, ‘2014’, ‘2015’, ‘2016’, ‘2017’, ‘2018’, ‘2019’, ‘2019.10’, ‘2019.11’, ‘2019.12’, ‘2020.1’, ‘2020.2’, ‘2020.3’, ‘2020.4’, ‘2020.5.22’, ‘2020.5.25’, ‘2020.5.26’, ‘2020.5.27’, ‘2020.5.28’, ‘2020.5.29’], [‘2.72’, ‘2.49’, ‘1.76’, ‘1.49’, ‘1.44’, ‘1.68’, ‘1.69’, ‘1.46’, ‘1.52’, ‘1.53’, ‘1.47’, ‘1.42’, ‘1.23’, ‘1.10’, ‘1.02’, ‘1.02’, ‘1.02’, ‘1.02’, ‘0.81’, ‘0.81’], [‘-0.58’, ‘-0.23’, ‘-0.73’, ‘-0.27’, ‘-0.05’, ‘0.24’, ‘0.01’, ‘-0.08’, ‘0.06’, ‘0.01’, ‘-0.06’, ‘-0.05’, ‘-0.19’, ‘-0.13’, ‘0.00’, ‘0.00’, ‘0.00’, ‘0.00’, ‘-0.21’, ‘0.00’]) |