eunja511005 / AutoCoding

0 stars 0 forks source link

셀레니움 이용해서 로그인 한 후 데이터 가져 오기 #182

Open eunja511005 opened 2 months ago

eunja511005 commented 2 months ago

1. 크롬 드라이브 다운로드

image  

2. 자신의 웹브라우져 버젼에 맞는걸로 다운로드

image

image

image

image  

3. 압축해제 후 D드라이브 하위로 복사

image

image  

4. pip install selenium pyperclip pandas openpyxl

image  

5. Element 찾기

1. 개발자 도구를 열어서 돋보기 버튼을 클릭 한 후 찾고자 하는 화면을 클릭 한다.
2. 찾고자 하는 엘레먼트의 id나 class를 확인 한 후 Ctrl + F를 이용하여 해당 엘레먼트가 화면에 몇개 있는지 확인 한다. 
  ※ id를 이용하여 찾기 : #id 
      class를 이용하여 찾기 : .input_text 
      부모와 자식 관계를 이용하여 찾기 : div > input 

image  

6. 파이썬 코딩

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import pyperclip
import time

# 브라우져 생성
browser = webdriver.Chrome()

# 웹싸이트 열기
browser.get('https://nid.naver.com/nidlogin.login?mode=form&url=https://www.naver.com/')
browser.implicitly_wait(10) # 로딩이 끝날 때까지 10초까지는 기다려 줌

# CSS_SELETOR를 이용하여 id 입력 창을 찾고 클릭하도록 함 
browser.find_element(By.CSS_SELECTOR,'#id').click()

# 화면이 뜰 때 시간이 걸릴 수 있으므로 잠깐 텀을 준 후 id, pw 입력
time.sleep(2)

# 캡챠 보안 회피를 위해 pyperclip 이용
pyperclip.copy('test')
browser.find_element(By.CSS_SELECTOR, '#id').send_keys(Keys.CONTROL+'v')
pyperclip.copy('test')
browser.find_element(By.ID, 'pw').send_keys(Keys.CONTROL+'v')
browser.find_element(By.CSS_SELECTOR, '.btn_login').click()
eunja511005 commented 2 months ago
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import StaleElementReferenceException
import pyperclip
import time

# 브라우져 생성
browser = webdriver.Chrome()

# 웹싸이트 열기
#browser.get('https://test.com/login.do')
browser.get('https://dev-test/login.do')
#browser.implicitly_wait(10) # 로딩이 끝날 때까지 10초까지는 기다려 줌

# WebDriverWait 객체 생성, 최대 대기 시간 설정 (예: 10초)
wait = WebDriverWait(browser, 10)

# CSS_SELETOR를 이용하여 id 입력 창을 찾고 클릭하도록 함 
# 특정 요소가 화면에 나타날 때까지 기다림
# 예: id가 'myElement'인 요소가 나타날 때까지 대기
id_element = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,'#id')))
#browser.find_element(By.CSS_SELECTOR,'#id').click()

# 캡챠 보안 회피를 위해 pyperclip 이용
pyperclip.copy('test')
id_element.send_keys(Keys.CONTROL+'v')
pyperclip.copy('test)
browser.find_element(By.ID, 'pw').send_keys(Keys.CONTROL+'v')
browser.find_element(By.CSS_SELECTOR, '.u_login_btn').click()

# 메뉴 클릭
# 화면이 뜰 때 시간이 걸릴 수 있으므로 잠깐 텀을 준 후 메뉴 클릭 하도록
#time.sleep(10)
#browser.find_element(By.CSS_SELECTOR, '#l3M010301 > a').click()
menu_element = WebDriverWait(browser, 10).until(
    EC.visibility_of_element_located((By.CSS_SELECTOR, '#l3M010301 > a'))
)
# 화면에 메뉴 엘레먼트가 보이더라도 로딩바로 인해 클릭 할수 없는 상태 이므로 스크립트를 바로 수행하도록 함.
browser.execute_script("arguments[0].click();", menu_element)

# iframe 변경이 일어난 후, 새 iframe으로 포커스 전환
# 새 iframe을 찾기 위해 명시적으로 대기
WebDriverWait(browser, 10).until(
    EC.frame_to_be_available_and_switch_to_it((By.ID, "contentsFrame"))
)

# iframe 내부의 요소가 로드될 때까지 기다림
select_element = WebDriverWait(browser, 10).until(
    EC.visibility_of_element_located((By.ID, "customerCd"))
)

# Select 객체 생성
select_object = Select(select_element)

# 옵션 선택하는 방법들:
#select_object.select_by_visible_text("6030455  ABC SAM TELECOMUNICACOES LTDA") # 텍스트로 선택
select_object.select_by_value('6030455') # 값(value)으로 선택
#select_object.select_by_index(0) # 인덱스로 선택 (인덱스는 0부터 시작)

search_button_element = WebDriverWait(browser, 10).until(
    EC.visibility_of_element_located((By.CSS_SELECTOR, '#searchButton > a'))
)
# 셀렉트 박스 선택 하고는 로딩바가 안나타나도록 웹페이지 구현 되어 있어 여기서는 스크립트 실행 안하고 버튼 클릭으로 가능
search_button_element.click()

# 조회 버튼 클릭후 로딩바 사라질때까지 기다림
WebDriverWait(browser, 10).until(
    EC.invisibility_of_element_located((By.ID, "loadingHtmlArea"))
)

element = WebDriverWait(browser, 10).until(
    EC.presence_of_element_located((By.ID, "tblGridResult"))
)

def get_table_data(driver, table_id):
    """테이블 데이터를 가져오는 함수."""
    try:
        # 테이블 요소가 로드될 때까지 기다립니다.
        table = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.ID, table_id))
        )

        # 'tr' 요소들에 대한 기다림은 'td' 요소들이 로드될 때까지 기다리는 것으로 대체됩니다.
        # 첫 번째 'tr'의 첫 번째 'td'가 로드될 때까지 기다립니다. 이는 테이블의 데이터 로드 시작을 나타냅니다.
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, f"#{table_id} tr td"))
        )

        # 테이블의 모든 행을 찾습니다.
        rows = table.find_elements(By.TAG_NAME, 'tr')

        # 데이터를 담을 이차원 배열을 준비합니다.
        table_data = []

        # 각 행과 열을 순회하며 데이터를 출력합니다.
        for row in rows:

            # 각 행의 데이터를 담을 리스트를 준비합니다.
            row_data = []

            cols = row.find_elements(By.TAG_NAME, 'td')
            for col in cols:
                # 각 셀의 텍스트에서 공백을 제거하고 리스트에 추가합니다.
                row_data.append(col.text.strip())

            table_data.append(row_data) 

        return table_data

    except StaleElementReferenceException:
        # 요소가 stale 상태일 경우, 다시 시도
        return get_table_data(driver, table_id)

# 테이블 데이터 조회
table_data = get_table_data(browser, 'tblGridResult')

print(table_data)
ywbestPark commented 2 months ago
import pandas as pd
from openpyxl import load_workbook
from openpyxl.styles import PatternFill

# 데이터 프레임 생성
data = {'이름': ['홍길동', '이순신', '강감찬'],
        '나이': [30, 35, 40],
        '도시': ['서울', '부산', '광주']}
df = pd.DataFrame(data)

# 엑셀 파일로 저장
file_path = 'example.xlsx'
df.to_excel(file_path, index=False, engine='openpyxl')

# 저장된 엑셀 파일 불러오기
workbook = load_workbook(filename=file_path)
sheet = workbook.active

# 제목 행 배경색 설정 (예: 노란색)
for cell in sheet[1]:
    cell.fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")

# 컬럼 너비 자동 조정
for column_cells in sheet.columns:
    length = max(len(str(cell.value)) for cell in column_cells)
    sheet.column_dimensions[column_cells[0].column_letter].width = length

# 변경사항 저장
workbook.save(file_path)
eunja511005 commented 2 months ago

최종 소스

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pandas as pd

def wait_for_js_function(driver, func_name):
    """ Check if a JavaScript function is defined """
    try:
        driver.execute_script(f"return {func_name};")
        return True
    except:
        return False

def execute_dynamic_link(driver, url):
    """ Execute a JavaScript function and measure iframe loading time """
    start_time = time.time()
    driver.execute_script(f"openMenuLink('{url}', this);")
    WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'contentsFrame')))
    WebDriverWait(driver, 10).until(lambda x: x.execute_script("return document.readyState === 'complete'"))
    end_time = time.time()
    driver.switch_to.default_content()
    return end_time - start_time

def login_and_perform_tasks(driver, login_url, pages, user_id, user_pw):
    """ Log in and perform tasks on different pages """

    driver.get(login_url)
    WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, '#id'))).send_keys(user_id)
    WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, 'pw'))).send_keys(user_pw)
    driver.find_element(By.CSS_SELECTOR, '.u_login_btn').click()
    WebDriverWait(driver, 10).until(lambda x: wait_for_js_function(x, "openMenuLink"))

    load_times = {page: execute_dynamic_link(driver, page) for page in pages}
    return load_times

def save_to_excel(login_url, load_times):
    """ Save the load times data to an Excel file """
    df = pd.DataFrame(list(load_times.items()), columns=['check_url', 'loading_time'])
    df['loading_time'] = df['loading_time'].apply(lambda x: f"{x:.3f} seconds")
    with pd.ExcelWriter('Load_Times.xlsx', engine='openpyxl') as writer:
        df.to_excel(writer, index=False, sheet_name=login_url.strip('https://').replace('.sec.samsung.com/login.do', ''))

def main():
    """ Main execution function """
    driver = webdriver.Chrome()
    login_url = 'https://dev-test.com/login.do'
    user_id = 'test'
    user_pw = 'test'
    pages_to_check = ["normalPlaceOrderNew.do", "ShopMaster.do", "logout.do"]

    load_times = login_and_perform_tasks(driver, login_url, pages_to_check, user_id, user_pw)

    # Save results to Excel
    save_to_excel(login_url, load_times)

    for page, time in load_times.items():
        print(f"Loading time for {page}: {time:.3f} seconds")

    driver.quit()

if __name__ == "__main__":
    main()