311 lines
22 KiB
Plaintext
311 lines
22 KiB
Plaintext
안녕? 한글로 얘기해.
|
|
나는 온라인 셀링을 하는 사업가야. 필요한 프로그램이 있어서 직접 코딩하는 중이야. 내가 원하는 프로그램을 완성해 줄래?
|
|
차근차근 진행해 보자.
|
|
|
|
전체코드의 구조를 검토해 보고 , 효율적으로 수정해 나가보자.
|
|
|
|
|
|
프로그램 아웃라인
|
|
1. 이 프로그램의 목적은 'percenty.co.kr'이라는 웹사이트에 접속 후 로그인 하고,
|
|
'마켓 설정'에 존재하는 각 마켓들의 'API key'를 바꾸는 프로그램이야.
|
|
2. 마켓은 현재 '쿠팡,' 스스', 'ESM', '11번가-국내', '11번가-해외', , '롯데온'이야. 추후에 더 추가될 수도 있어.
|
|
마켓마다 요구하는 api키의 종류는 다양하고 해당부분은 추가되어 있어.
|
|
3. 이 프로그램을 사용하는 사람은 사업자가 여러개 있을 수 있고, 사업자마다 마켓별 api키를 가지고 있지.
|
|
4. 프로그램 설정으로 저장할 수 있는 총 사업자 숫자를 제한할 수 있어야 해.
|
|
5. 각각의 설정은 암호화되어 config.ini 파일에 저장되고, 프로그램이 실행되면 다시 불러오게 해야해.
|
|
6. 디버깅을 위해 로그는 로그파일과 콘솔출력 모두 되어야 하고, 디버깅레벨은 디버그, 디버깅이 끝난 후 배포단계에서는 Info로 변경해서 배포할꺼야.
|
|
|
|
UI 구성
|
|
1. pyqt5를 이용한 GUI프로그램이야. 웹과 상호작용하는 부분은 playwright의 비동기 기능을 이용해야해.
|
|
2. 프로그램이 실행되면 라이센스 동의 화면이 표시되. 이 화면에는 아랫쪽에 체크버튼이 있고, 체크버튼을 클릭하면 Acept버튼이 활성화 되. 취소 버튼은 항상 활성화 되어있고, 이걸 누르면 프로그램이 종료되.
|
|
3. Accept버튼을 클릭하면 라이센스 동의화면이 없어지고 본 기능을 하는 메인윈도우가 표시되.
|
|
4. 메인 윈도우에는 '도움말', '퍼센티설정', '사업자설정'이라는 메뉴 item이 있어.
|
|
5. '도움말'을 누르면 QTextBrowser 가 실행되고 그 내부에 도움말을 표시할꺼야.
|
|
6. '퍼센티설정'을 누르면 사용자 아이디와 비밀번호를 입력받는 작은 위젯이 실행되고, 저장버튼과 취소버튼으로 구성되어있고, 저장 버튼을 누르면 설정이 저장되.
|
|
7. '사업자 설정'을 누르면 별도의 사업자설정 위젯이 생겨. 여기는 사업자마다 탭으로 구성되어있고, 탭 내부의 상단레이아웃에는 사업자 정보, 하단레이아웃은 다시 마켓별 탭이 있고, 탭마다 마켓의 api키들을 저장할 수 있는 qlabel과 qtextedit가 쌍을 이루면서 존재해.
|
|
|
|
8. 메인 윈도우는 mainLayout으로 qvlayout을 사용해.
|
|
9. mainLayout의 내부 구성레이아웃으로 3개의 layout들이 있어. 각각 20%, 60% 20%의 면적을 차지해.
|
|
10. 1번 qhlayout은 SettingButtonLayout으로 '현재설정 가져오기' 버튼과 '현재설정 저장하기' 버튼이 있어.
|
|
10. 현재설정 가져오기 버튼을 누르면 playwright가 비동기로 실행되어 웹사이트에 접속 후 로그인하고, 현재의 마켓설정들을 가져와.
|
|
11. 현재설정 저장하기 버튼을 누르면 '사업자 저장' 위젯이 떠.
|
|
12. '사업자 저장 위젯'은 사업자 별칭, 사업자등록번호, 상호명, 등록날짜, 응대전화번호를 입력하는 칸이 있어. 해당 칸들을 채운 후 취소버튼과 확인버튼 중 확인버튼을 누르면 해당사업자로 저장되.
|
|
13. 이때 현재 등록된 사업자 숫자가 총 등록된 사업자 숫자보다 많은 경우 에러 메세지를 띄워줘.
|
|
13. '사업자 저장 위젯'의 필수 입력정보는 사업자등록번호, 상호명이며 사업자별칭이 비어있으면 상호명이 이곳에 들어가면 되.
|
|
|
|
14. 2번 qhlayout은 currentStatusLayout으로 실제 웹사이트에 접속 후 가져온 데이터를 표시해 주는곳이야.
|
|
15. 2번 qhlayout은 3개의 박스로 구성 되어있어.
|
|
16. 2번 qhlayout 의 첫번째 박스는 현재 사업자 현황을 보여주는 박스가 표시되. 30%를 차지하는데, 가져온 데이터가 저장된 사업자데이터와 일치하는 경우 그 사업자의 사업자별칭, 사업자등록번호, 상호명, 등록날짜, 응대전화번호가 표시되.
|
|
17. 2번 qhlayout 의 두번째 박스는 60%를 차지하는데 내부에는 다시 qhlayout으로 만들어진 marketqhlayout 레이아웃은 마켓별로 구성되고, 여기에는 마켓이름을 표시하는 qpushbutton과 사업자별칭을 표시하는 qplaintext가 있어.
|
|
18. 가져온 데이터의 마켓별 api키가 저장된 사업자들 중 일치하는 사업자가 있으면 해당 마켓 라벨의 배경을 연두색으로 하고, 사업자의 별칭을 보여줘.
|
|
19. 만약 일치하는 사업자가 없다면 배경을 진한회색으로 변경하고 "NoMatch"로 표시하면 되.
|
|
20. 2번 qhlayout 의 세번째 박스 10%를 차지하고 내용은 일단 비워줘.
|
|
|
|
21. 3번 qvlayout은 selectSettingLayout으로 '사업자 드롭박스', '마켓 체크박스'와 '사업자 바꾸기' 버튼, '진행상황' 프로그레스바가 있어.
|
|
22. selectSettingLayout은 '사업자 드롭박스' 위젯1개, '마켓 체크박스'를 표시할 레이아웃 1개, '사업자 바꾸기' 위젯1개, '진행상황' 위젯 1개로 구성되.
|
|
22 '사업자 드롭박스'에는 '사업자설정'에서 마켓별 api가 1개라도 설정된 사업자만 표시되.
|
|
23. 마켓 체크박스 레이아웃은 마켓이름으로 구성된 체크박스들이 3열로 구성되어 있어. 추후 지원하는 마켓이 늘어나면 이곳에도 추가로 늘어날 예정이야.
|
|
24. 마켓 체크박스 레이아웃' 내부에는 '전체선택' 이라는 체크박스와 함께 모든 마켓들이 표시되. 그런데 '사업자 드롭박스'에서 선택된 사업자의 마켓 중 api값이 없는 마켓은 체크할 수 없게 비활성화 되어야 해.
|
|
25. '사업자바꾸기' 버튼을 누르면 선택된 사업자와 선택된 마켓을 기준으로 실제 바꾸는 동작을 해야해. 이 동작은 playwright의 비동기작업으로 실행되.
|
|
26. 이때 작업 진행상황은 '진행상황'프로그레스 바에 업데이트 시켜줘.
|
|
26. 사업자 api가 모두 바꿔지면 '현재설정 가져오기' 의 연결된 메서드 동작 중 현재마켓 설정을 가져오는 메서드만 동작하여 currentStatusLayout의 내용을 업데이트 시켜야 해.
|
|
27. 작업이 완료되면 작업완료 창을 띄워줘.
|
|
28. 작업완료창은 현황 레이아웃 ('사용자에게 바뀌기전 사업자 현황'과 '바뀐 사업자 현황'으로 구성), '브라우저 실행' 버튼과 '확인'버튼으로 구성되어 있어.
|
|
29. 작업완료창의 확인 버튼을 누르면 창이 사라지고, 브라우저 실행 버튼을 누르면 playwright의 chrome이 headless=false 모드로 실행되면서 작업완료 창은 사라져.
|
|
30. 사용자가 브라우저 실행 버튼을 누르면서 실행된 playwright는 이제부터 사용자가 웹사이트 작업을 할꺼야. 그래서 기존에 사업자 정보를 불러왔던 객체와는 별도의 객체여야 해.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
사업자 설정 버튼을 누르면 나오는 ui를 정의해야 해.
|
|
|
|
이 파일은 클래스 파일이고 내부에는 기본적은 클래스변수를 포함해 initIU메서드와 함께 여러 기능을 하는 메서드들이 포함되어야 해.
|
|
모든 사용자에게 입력받는 모든 데이터는 클래스 변수로 설정되고 메서드들은 그 값들을 이용할 꺼야.
|
|
그리고 이 클래스변수에 접근하는 메서드들도 포함해줘,
|
|
|
|
동작 정의
|
|
기본적으로 다른 main 프로그램에 import되어 입력버튼을 누르는 등의 동작에 연결되어 해당하는 위젯이 표시되어야 해.
|
|
그래서 처음 main 프로그램이 시작할때 이 클래스의 객체를 생성하고, 필요한 동작이 호출되면 UI를 show 시키는 방식으로 동작하는게 좋겠어.
|
|
이 부분은 더 좋은 방법이 있으면 추천해줘
|
|
|
|
UI 정의
|
|
|
|
1. 메인 레이아웃은 QFRAME 안에 QVLAYOUT이 설정되어있어. 그 안애는 상단에 10%의 면적을 차지하는 QHLAYOUT이 1개 있고 여기에는 저장,삭제, 취소 버튼이 있고, 설정마켓 버튼이 있어.
|
|
저장,삭제,취소 버튼은 해당 메서드에 연결되어 있고, 이 부분은 추후에 구현할 예정이니 그냥 PASS와 함께 해당버튼을 눌렀다는 PRINT문만 추가해줘.
|
|
설정마켓 버튼은 클릭하면 작은 위젯이 하나 생성되는데, 여기서는 1행1열의 전체선택 체크박스와 3X3의 각 마켓의 체크박스가 함께 있어. 그리고 확인 버튼과 취소 버튼이 있지.
|
|
기본설정은 모든 마켓이 체크되어있어. 그리고 체크박스의 상태에 따라 마켓정보가 있는 QTABWIDGET 표시된 마켓의 탭을 보여줄지 말지의 여부를 결정할 꺼야. 이 버튼은 각각의 사업자 마다 동작해.
|
|
|
|
그 아래에는 QTABWIDGET이 있고 90%의 면적을 차지해.
|
|
|
|
2. QTABWIDGET의 탭의 갯수는 클래스 변수에 설정된 MAX_BUSINESS_COUNT 값이야. 이 값은 클래스 객체를 생성할때 인자로 받는 값이야.
|
|
각 탭의 제목은 기본값은 '1사업자', '2사업자', 등이 될꺼고, 만약 해당탭 내부의 '사업자 별칭'에 값이 있다면 그 값으로 설정되어야 해.
|
|
탭이 선택되면 해당 탭은 색이 연두색으로 변해.
|
|
|
|
QTABWIDGET은 테두리가 설정되어있고, 내부에는 QVLAYOUT이 설정되어 있어. 그리고 2개의 QFRAME으로 상단에는 사업자 정보 (40%면적차지), 하단에는 마켓정보(60%면적차지)가 들어갈 꺼야.
|
|
그 중 사업자 정보 QFRAME의 내부는 qgridlayout이 있고, 내부 구조는 다음과 같아
|
|
1행 에는 2개 열이 있고 1열에는 '사업자 별칭' 라벨, 2열에는 해당값을 입력할 수 있는 QLineedit가 있어.
|
|
2행 에는 4개 열이 있고 각각 사업자 등록번호, 상호명, 등록날짜, 전화번호 의 Qlabel이 가운데 정렬로 있어.
|
|
3행 에는 4개의 열이 있고 각각 2열에 해당하는 값을 입력할 수 있도록 Qlineedit가 있어.
|
|
4행 에는 4개 열이 있고 각각 기타 정보1, 기타정보2, 기타정보3, 기타정보4 의 Qpushbutton이 있어.
|
|
기타정보의 각 버튼을 누르면 간단한 텍스트를 입력할 수 있는 다이알로그가 떠. 창에는 레이아웃이 3개 있고, 첫번째 QHLAYOUT에는 '제목' 텍스트의 QLABEL과 사용자가 편집할 수 있는 QLINEEDIT 3:7의 비율로 있어. 두번째 QVLAYOUT에는 '내용' 텍스트의 QLABEL과 QTEXTBROWSER가 있어. 세번째 QHLAYOUT에는 확인버튼과 취소버튼이 있어.
|
|
확인 버튼을 누르면 기타정보 버튼의 텍스트가 제목 으로 설정된 텍스트로 바껴.
|
|
|
|
3. 마켓정보 QFRAME에도 역시 QTABWIDGET이 있고, 여기에는 탭마다 해당 사업자의 각 마켓 정보가 들어갈 꺼야.
|
|
마켓정보를 담은 QTABWIDGET은 선택된 탭은 연두색으로 변해.
|
|
탭 이름은 마켓이름이고(쿠팡,스마트스토어,ESM,11번가-국내,11번가-글로벌,롯데온,인터파크,위메프,옥션1.0)
|
|
탭 내부에는 QGRIDLAYOUT으로 설정되어있어.
|
|
기본적으로 4열로 구성되어있고, 1열, 3열에는 값 이름, 2열 4열에는 각각 1열,3열에 해당하는 값을 입력할 수 있는 QLINEEDIT가 있어.
|
|
- '쿠팡' 1행 : 쿠팡ID, 업체코드
|
|
- '쿠팡' 2행 : Access Key','Secret Key'
|
|
- '스마트스토어' 1행 :'업로드 할 스마트스토어 계정 ID','업로드 할 스마트스토어 계정 PW',
|
|
- '스마트스토어' 2행 :'애플리케이션 ID','애플리케이션 시크릿'
|
|
- 'ESM' 1행 :'옥션ID','G마켓 ID'
|
|
- '11번가-국내' 1행 :'API KEY'
|
|
- '11번가-글로벌' 1행 :'API KEY'
|
|
- '롯데온' 1행 :'API KEY'
|
|
- '인터파크' 1행:'상품상태재고수정 인증키','상품상태재고수정 비밀키'
|
|
- '인터파크' 2행'상품재고조회 인증키','상품재고조회 비밀키'
|
|
- '인터파크' 3행'상품정보조회 인증','상품정보조회 비밀키'
|
|
- '인터파크' 4행'상품수정 인증키','상품수정 비밀키'
|
|
- '인터파크' 5행'상품등록 인증키','상품등록 비밀키'
|
|
- '인터파크' 6행'반품배송지조회 인증키','반품배송지조회 비밀키'
|
|
- '인터파크' 7행'반품배송지등록 인증키','반품배송지등록 비밀키'
|
|
- '인터파크' 8행'상품QnA등록 인증키','상품QnA등록 비밀키'
|
|
- '인터파크' 9행'상품QnA조회 인증키','상품QnA조회 비밀키'
|
|
- '인터파크' 10행'인터파크 업체번호','공급계약 일련번호'
|
|
- '위메프' 1행:'API KEY'
|
|
- '옥션1.0' 1행:'멤버 ID'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
기타 정보 버튼 아래에 4개의 버튼을 추가로 만들어줘.
|
|
이 버튼들은 '사업자등록증', '통신판매업신고증', '사업자통장', '기타이미지' 의 텍스트를 가지고 있어.
|
|
이 버튼을 클릭하면 작은 위젯이 생성되고, 위젯에는 4:3 비율의 이미지를 표시할꺼야.
|
|
사업자등록증이나 통신판매업 신고증 같은 A4용지를 스캔한 이미지를 표시할 예정이야.
|
|
|
|
UI의 구성은 아래와 같아.
|
|
qvlayout을 메인레이아웃으로 하고 그 내부에 2개의 qhlayout이 있어. 첫번째는 10%의 면적을 차지하고 확인 버튼, 저장 버튼, 삭제버튼이 있어.
|
|
두번째 qhlayout은 나머지 90%의 면적을 차지하고 내부에는 이미지를 표시하는 위젯이 있어.
|
|
|
|
|
|
|
|
이 모든 정보를 저장하기 위해 실행폴더에 My_BUSINESS_Info 폴더를 만들고 해당폴더 아래에 각 사업자 별로 정보를 저장해야 해.
|
|
각 사업자 정보는 BUSINESS_INFO_1,BUSINESS_INFO_2,BUSINESS_INFO_3,BUSINESS_INFO_4,BUSINESS_INFO_5 폴더가 있고,
|
|
해당 사업자 폴더 아래에는 business_info.ini 파일, etc_info.ini파일, image폴더, pdf폴더, etc폴더가 있어.
|
|
business_info.ini파일에는 사업자 정보(사업자등록번호 등)과 각 마켓의 api정보를 담고 있어.
|
|
etc_info.ini파일에는 기타 정보에서 설정한 내용들이 들어있어.
|
|
image폴더에는 사업자등록증이나 통신판매업 신고증 같은 이미지파일들이 있고, pdf폴더에는 교육 수료증이나 판매허가증 같은 pdf 파일들이 있어.
|
|
etc폴더에는 위의 내용을 제외한 나머지 사업폴더들이 존재할꺼야.
|
|
|
|
이렇게 폴더구조를 만든 후 이 내용들을 구글드라이브와 동기화 시키는 옵션을 만들고, My_BUSINESS_Info 폴더가 업데이트 될때 마다 동기화를 시키면 좋겠어.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
아래의 코드를 처리하는 중 예상치 못한 상황이 발생했어.
|
|
|
|
id와 pw를 입력 후 로그인버튼을 누르면 일반적으로 로그인이 성공하는데, 그 중간에 2단계 인증을 하는 경우가 가끔 있어.
|
|
이 상황을 해결하는 코드가 필요해
|
|
|
|
2단계 인증에 관한 css는 아래와 같아.
|
|
2단계 인증이 활성화 된 경우 사용자에게 메세지를 표시하고, headless모드를 풀어서 팝업 윈도우를 사용자에게 보여주어야 해.
|
|
그래서 사용자가 선호하는 방법으로 2단계인증을 완료하고 팝업창을 종료할때까지 대기해야해.
|
|
|
|
[코드]
|
|
# 스마트스토어의 경우 로그인 작업 수행
|
|
if market == '스마트스토어' and key == '업로드할스마트스토어계정명':
|
|
print(f"스마트스토어 작업 시작")
|
|
|
|
# 새 창이 열리는 이벤트를 기다림
|
|
async with self.page.context.expect_page() as new_page_info: # 새 팝업이 아닌 새창
|
|
await self.page.click(self.smartstore_elements['account_button'])
|
|
print(f"page.click - account_button")
|
|
|
|
popup_page = await new_page_info.value
|
|
print(f"새 창 열림: {popup_page.url}")
|
|
|
|
await popup_page.wait_for_load_state()
|
|
print("새 창 로드 완료")
|
|
|
|
await popup_page.evaluate('document.querySelector(arguments[0]).scrollIntoViewIfNeeded()', self.smartstore_elements['popup_login_type_button'])
|
|
await popup_page.click(self.smartstore_elements['popup_login_type_button'])
|
|
print(f"page.click - popup_login_type_button")
|
|
|
|
await popup_page.evaluate('document.querySelector(arguments[0]).scrollIntoViewIfNeeded()', self.smartstore_elements['popup_login_id_input'])
|
|
await popup_page.fill(self.smartstore_elements['popup_login_id_input'], market_api_keys.get('업로드할스마트스토어계정id', ''))
|
|
print(f"page.fill - 업로드할스마트스토어계정id")
|
|
|
|
await popup_page.fill(self.smartstore_elements['popup_login_pw_input'], market_api_keys.get('업로드할스마트스토어계정pw', ''))
|
|
print(f"page.fill - 업로드할스마트스토어계정pw")
|
|
|
|
await popup_page.evaluate('document.querySelector(arguments[0]).scrollIntoViewIfNeeded()', self.smartstore_elements['popup_login_button'])
|
|
await popup_page.click(self.smartstore_elements['popup_login_button'])
|
|
print(f"page.click - popup_login_button")
|
|
|
|
try:
|
|
# 팝업 페이지가 닫혀 있는지 확인
|
|
if popup_page.is_closed():
|
|
print("팝업 페이지가 닫혔습니다. 로그인 성공으로 간주합니다.")
|
|
else:
|
|
# 로그인 성공 확인
|
|
login_success = await popup_page.inner_text(self.smartstore_elements['login_success_check'])
|
|
if login_success != market_api_keys.get('업로드할스마트스토어계정id', ''):
|
|
print("스마트스토어 로그인 실패")
|
|
return
|
|
|
|
# 팝업 닫기
|
|
await popup_page.close()
|
|
except Exception as e:
|
|
print(f"로그인 팝업윈도우 처리 중 에러발생 : {e}")
|
|
traceback.print_exc()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[2단계인증 관련]
|
|
"div#root h2"의 요소의 값이 "2단계 인증" 일 경우 2단계 인증 발생으로 간주
|
|
|
|
아래의 2개 중 1개로 해결해야 함.
|
|
2개중 1개는 활성화 되어 있고, 활성화된 버튼은 아래처럼 표시됨.
|
|
활성화된 버튼의 css : "div#root li.TwoStepCertify_choice_item__2qian.TwoStepCertify_on__2Y_8N > label"
|
|
|
|
1. '휴대전화 인증'이 활성화 된 경우 '이메일 인증' 활성화 버튼 : "div#root li:nth-child(1) > label"
|
|
2. 이메일 인증 보내기 버튼 : "div#root div.TextField_text_field__x1Wtz.TextField_field_email__2BzY5.TextField_disabled__2mxn3 > div > div > div.TextField_btn_box__2TdIe > button[type=\"button\"]"
|
|
3. '이메일 인증'이 활성화 된 경우 '휴대전화 번호로 인증' 활성화 버튼 : "div#root li:nth-child(2) > label"
|
|
4. 휴대전화 번호로 인증 보내기 버튼 : "div#root div.TextField_text_field__x1Wtz.TextField_field_phone__3MV-T.TextField_disabled__2mxn3 > div > div.TextField_ipt_area__3lD1U > div.TextField_btn_box__2TdIe > button[type=\"button\"]"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
아래의 요소들을 다시 반영해줘.
|
|
|
|
[2단계인증 관련]
|
|
"div#root h2"의 요소의 값이 "2단계 인증" 일 경우 2단계 인증 발생으로 간주
|
|
|
|
아래의 2개 중 1개로 해결해야 함.
|
|
2개중 1개는 활성화 되어 있고, 관련 CSS 요소는 아래와 같아.
|
|
|
|
2개의 인증방법 중 1개를 선택하고 인증 버튼을 누르면 창 내부에 '인증전송 확인' 팝업이 뜨고, 해당 팝업의 확인 버튼을 누르면 인증번호 입력칸이 생겨.
|
|
제한시간이 3분가량 있고, 역으로 카운트 되. 해당시간 내에 정확안 인증번호를 넣으면 확인버튼이 활성화 되고 해당 버튼을 누르면 로그인 절차가 완료되.
|
|
|
|
|
|
[CSS 요소]
|
|
활성화된 버튼의 css : "div#root li.TwoStepCertify_choice_item__2qian.TwoStepCertify_on__2Y_8N > label"
|
|
|
|
1. '휴대전화 인증'이 활성화 된 경우 '이메일 인증' 활성화 버튼 : "div#root li:nth-child(1) > label"
|
|
2. 이메일 인증 보내기 버튼 : "div#root div.TextField_text_field__x1Wtz.TextField_field_email__2BzY5.TextField_disabled__2mxn3 > div > div > div.TextField_btn_box__2TdIe > button[type=\"button\"]"
|
|
3. '이메일 인증'이 활성화 된 경우 '휴대전화 번호로 인증' 활성화 버튼 : "div#root li:nth-child(2) > label"
|
|
4. 휴대전화 번호로 인증 보내기 버튼 : "div#root div.TextField_text_field__x1Wtz.TextField_field_phone__3MV-T.TextField_disabled__2mxn3 > div > div.TextField_ipt_area__3lD1U > div.TextField_btn_box__2TdIe > button[type=\"button\"]"
|
|
|
|
|
|
이메일 인증이 활성화 되었을 때 보이는 '인증용 이메일 주소' : input#auth_id.TextField_ipt__33BFT[placeholder='2단계 인증 이메일']
|
|
휴대전화 인증이 활성화 되었을 때 보이는 인증용 휴대전화 번호 : input#phone[placeholder='내용을 입력해주세요']
|
|
|
|
|
|
이메일 인증번호를 전송했을때 전송되었다는 확인팝업의 확인버튼 : div#root button.PopupCommon_btn__33Of5[type='button']
|
|
이메일 주소 인증의 인증번호 입력칸 : div#root input.TextField_ipt__33BFT[inputmode='numeric'][placeholder='인증번호 숫자 6자리']
|
|
이메일 주소 인증의 인증번호 입력 취소버튼 : "div#root div.TextField_text_field__x1Wtz.TextField_field_email__2BzY5.TextField_disabled__2mxn3 > div > div > div.TextField_btn_box__2TdIe > button[type=\"button\"]"
|
|
이메일 주소 인증의 인증 유효시간 :"div#root div.TextField_time__1AWa7 > span"
|
|
|
|
|
|
휴대전화 인증번호를 전송했을때 전송되었다는 확인팝업의 확인버튼 : div#root button.PopupCommon_btn__33Of5[type='button']
|
|
휴대전화 인증의 인증번호 입력칸 : div#root input.TextField_ipt__33BFT[inputmode='numeric'][placeholder='인증번호 숫자 6자리']
|
|
휴대전화 인증의 인증번호 입력 취소버튼 : "div#root div.TwoStepCertify_certify_num__1m4OX > div > div.TextField_ipt_item__1AOpe > div > div.TextField_btn_box__2TdIe > button[type=\"button\"]"
|
|
휴대전화 인증의 인증 유효시간 : "div#root div.TextField_time__1AWa7 > span"
|
|
|
|
|
|
인증번호 입력 후 확인 버튼 : div#root .TwoStepCertify_btn_box__3TSSP .Button_btn_plain__1j7dG[type='button'] |