bcpkgfox 0.17.4__py3-none-any.whl → 0.17.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bcpkgfox/invoke_api.py +117 -105
- bcpkgfox-0.17.5.dist-info/METADATA +45 -0
- {bcpkgfox-0.17.4.dist-info → bcpkgfox-0.17.5.dist-info}/RECORD +6 -8
- {bcpkgfox-0.17.4.dist-info → bcpkgfox-0.17.5.dist-info}/WHEEL +1 -1
- bcpkgfox/examples copy.py +0 -227
- bcpkgfox/examples.py +0 -153
- bcpkgfox-0.17.4.dist-info/METADATA +0 -53
- {bcpkgfox-0.17.4.dist-info → bcpkgfox-0.17.5.dist-info}/entry_points.txt +0 -0
- {bcpkgfox-0.17.4.dist-info → bcpkgfox-0.17.5.dist-info}/top_level.txt +0 -0
bcpkgfox/invoke_api.py
CHANGED
|
@@ -167,7 +167,7 @@ def invoke_api_proc_log(link, id_robo, token):
|
|
|
167
167
|
"POST", link, json=payload, headers=headers)
|
|
168
168
|
print(f"\n{responseinsert.json()}")
|
|
169
169
|
|
|
170
|
-
def login_2fac(driver, certificate, system, token, code_timeout=
|
|
170
|
+
def login_2fac(driver, certificate, system, token, code_timeout=10):
|
|
171
171
|
import requests
|
|
172
172
|
import pyautogui
|
|
173
173
|
from . import mostrar_mensagem
|
|
@@ -332,9 +332,13 @@ def login_2fac(driver, certificate, system, token, code_timeout=60):
|
|
|
332
332
|
self.driver.get('chrome-extension://lnidijeaekolpfeckelhkomndglcglhh/index.html')
|
|
333
333
|
|
|
334
334
|
def codes_2_fac(self):
|
|
335
|
-
|
|
335
|
+
element_sistema = '//input[(contains(@placeholder,"selecione um sistema pra acessar") or contains(@name, "system")) and contains(@role, "combobox")]'
|
|
336
|
+
element_email = '//input[contains(@placeholder,"Insira aqui o seu email") or contains(@placeholder,"e-mail")]'
|
|
337
|
+
email = 'eliezer@bcfox.com.br'
|
|
338
|
+
element_code = '//input[contains(@placeholder,"Digite aqui o código que enviamos para o seu e-mail") or contains(@placeholder,"código") or contains(@type,"password")]'
|
|
339
|
+
element_submit ='//button[contains(@type, "submit")]'
|
|
336
340
|
try:
|
|
337
|
-
tools.find_element_with_wait(By.XPATH, '
|
|
341
|
+
tools.find_element_with_wait(By.XPATH, f'{element_sistema}', timeout=2).send_keys(self.system)
|
|
338
342
|
code_insertion = True
|
|
339
343
|
|
|
340
344
|
except:
|
|
@@ -342,9 +346,9 @@ def login_2fac(driver, certificate, system, token, code_timeout=60):
|
|
|
342
346
|
|
|
343
347
|
# Request the code
|
|
344
348
|
for _ in range(50): # Wait the extension to load
|
|
345
|
-
|
|
349
|
+
time.sleep(1)
|
|
346
350
|
try:
|
|
347
|
-
tools.find_element_with_wait(By.XPATH, '
|
|
351
|
+
tools.find_element_with_wait(By.XPATH, f'{element_email}', timeout=1).send_keys(f'{email}')
|
|
348
352
|
time.sleep(1)
|
|
349
353
|
break
|
|
350
354
|
except:
|
|
@@ -353,137 +357,145 @@ def login_2fac(driver, certificate, system, token, code_timeout=60):
|
|
|
353
357
|
# Envia o código pro email, o for é só para tratativa de bugs
|
|
354
358
|
for _ in range(10):
|
|
355
359
|
try:
|
|
356
|
-
tools.find_element_with_wait(By.XPATH, '
|
|
360
|
+
tools.find_element_with_wait(By.XPATH, f'{element_code}', timeout=1)
|
|
357
361
|
break
|
|
358
362
|
|
|
359
363
|
except:
|
|
360
364
|
try:
|
|
361
|
-
element = tools.find_element_with_wait(By.XPATH, '
|
|
365
|
+
element = tools.find_element_with_wait(By.XPATH, f'{element_email}', timeout=1)
|
|
362
366
|
element.clear()
|
|
363
|
-
element.send_keys('
|
|
364
|
-
tools.find_element_with_wait(By.XPATH, '
|
|
367
|
+
element.send_keys(f'{email}')
|
|
368
|
+
tools.find_element_with_wait(By.XPATH, f'{element_submit}').click()
|
|
365
369
|
time.sleep(1)
|
|
366
370
|
except:
|
|
367
371
|
break
|
|
368
372
|
|
|
369
373
|
# Attempts the new codes until success or requests limit
|
|
370
374
|
for _ in range(code_timeout):
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
element = tools.find_element_with_wait(By.XPATH, '//input[@type="password"]')
|
|
381
|
-
element.clear()
|
|
382
|
-
element.send_keys(CODE)
|
|
383
|
-
|
|
384
|
-
for _ in range(10):
|
|
385
|
-
try:
|
|
386
|
-
tools.find_element_with_wait(By.XPATH, '//div/div[2]/button', timeout=2).click()
|
|
387
|
-
time.sleep(1)
|
|
388
|
-
except:
|
|
389
|
-
break
|
|
390
|
-
|
|
391
|
-
# Check the code result
|
|
392
|
-
for _ in range(30):
|
|
393
|
-
|
|
394
|
-
# Correct
|
|
395
|
-
try:
|
|
396
|
-
# input('\n\n > Selecione o sistema e aperte alguma tecla.')
|
|
397
|
-
tools.find_element_with_wait(By.XPATH, '//input[@placeholder="Digite ou selecione um sistema pra acessar"]', timeout=1).send_keys(self.system)
|
|
398
|
-
api.invoke_update_status(ID) #FIX: Update
|
|
399
|
-
code_insertion = True
|
|
400
|
-
break
|
|
401
|
-
|
|
402
|
-
except:
|
|
403
|
-
pass
|
|
375
|
+
def adicionar_code():
|
|
376
|
+
responses = api.invoke_get_codes()
|
|
377
|
+
if not responses:
|
|
378
|
+
time.sleep(2)
|
|
379
|
+
return [], None
|
|
380
|
+
# Try new codes
|
|
381
|
+
code_insertion = False
|
|
382
|
+
for response in responses:
|
|
383
|
+
time.sleep(1)
|
|
404
384
|
|
|
405
|
-
|
|
406
|
-
try:
|
|
407
|
-
tools.find_element_with_wait(By.XPATH, "//span[contains(text(), 'Senha inválida')]", timeout=1)
|
|
408
|
-
tools.find_element_with_wait(By.XPATH, "//button[text()='Voltar']", timeout=1).click()
|
|
409
|
-
code_insertion = False
|
|
385
|
+
if 'Escolha um certificado' in self.driver.page_source:
|
|
410
386
|
break
|
|
411
387
|
|
|
412
|
-
|
|
413
|
-
|
|
388
|
+
CODE = response['CODIGO']
|
|
389
|
+
ID = response['ID']
|
|
414
390
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
391
|
+
element = tools.find_element_with_wait(By.XPATH, '//input[@type="password"]')
|
|
392
|
+
element.clear()
|
|
393
|
+
element.send_keys(CODE)
|
|
394
|
+
button_entrar_click = False
|
|
395
|
+
for _ in range(20):
|
|
396
|
+
try:
|
|
397
|
+
button = tools.find_element_with_wait(By.XPATH, f'{element_submit}', timeout=2)
|
|
398
|
+
if button.get_attribute('disabled'):
|
|
399
|
+
time.sleep(1.5)
|
|
400
|
+
continue
|
|
401
|
+
button.click()
|
|
402
|
+
button_entrar_click = True
|
|
403
|
+
if 'Escolha um certificado' in self.driver.page_source:
|
|
404
|
+
break
|
|
405
|
+
|
|
406
|
+
time.sleep(1)
|
|
407
|
+
except:
|
|
408
|
+
break
|
|
409
|
+
|
|
410
|
+
if int(_) == 20 and button_entrar_click == False:
|
|
411
|
+
raise TimeoutError('Código Whom falhou ao entrar')
|
|
412
|
+
|
|
413
|
+
return responses, ID
|
|
414
|
+
|
|
415
|
+
responses, ID = adicionar_code()
|
|
416
|
+
|
|
417
|
+
if 'Sair' in self.driver.page_source and not 'Verifique seu e-mail' in self.driver.page_source:
|
|
418
|
+
api.invoke_update_status(ID) # FIX: Update
|
|
420
419
|
break
|
|
421
420
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
# Selects the system to access
|
|
426
|
-
lines = tools.find_elements_with_wait(By.XPATH, '//div[@role="menu"]//div[@role="menuitem"]')
|
|
421
|
+
if 'Verifique seu e-mail':
|
|
422
|
+
responses,ID = adicionar_code()
|
|
427
423
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
424
|
+
for _ in range(60):
|
|
425
|
+
if not(responses):
|
|
426
|
+
responses,ID = adicionar_code()
|
|
427
|
+
time.sleep(1)
|
|
428
|
+
else:
|
|
429
|
+
break
|
|
433
430
|
|
|
434
|
-
|
|
431
|
+
if not (responses):
|
|
432
|
+
raise TimeoutError('Código WHOOM não chegou dentro do timeout estabelecido')
|
|
433
|
+
# Wrong
|
|
435
434
|
|
|
436
|
-
|
|
437
|
-
|
|
435
|
+
try:
|
|
436
|
+
tools.find_element_with_wait(By.XPATH, "//span[contains(text(), 'Senha inválida')]",
|
|
437
|
+
timeout=1)
|
|
438
|
+
tools.find_element_with_wait(By.XPATH, "//button[text()='Voltar']", timeout=1).click()
|
|
439
|
+
code_insertion = False
|
|
440
|
+
break
|
|
438
441
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
if self.certificate.lower().strip() in titulo_text.lower().strip():
|
|
442
|
-
finded = True
|
|
443
|
-
continue
|
|
442
|
+
except:
|
|
443
|
+
pass
|
|
444
444
|
|
|
445
|
-
|
|
446
|
-
|
|
445
|
+
if 'Sair' in self.driver.page_source and not 'Verifique seu e-mail' in self.driver.page_source:
|
|
446
|
+
api.invoke_update_status(ID) # FIX: Update
|
|
447
|
+
break
|
|
447
448
|
|
|
448
|
-
|
|
449
|
-
|
|
449
|
+
code_insertion = False
|
|
450
|
+
# Check the code result
|
|
451
|
+
for _ in range(30):
|
|
452
|
+
if code_insertion:
|
|
453
|
+
break
|
|
454
|
+
# Correct
|
|
455
|
+
try:
|
|
456
|
+
tools.find_element_with_wait(By.XPATH,"//input[(contains(@name,'certificate') or contains(@placeholder,'certificado')) and not(contains(@type, 'hidden'))]", timeout=1).send_keys(self.certificate)
|
|
457
|
+
list_certific = tools.find_elements_with_wait(By.XPATH,'//div[contains(@role,"option")]')
|
|
458
|
+
list_certific[0].click()
|
|
459
|
+
time.sleep(1)
|
|
460
|
+
code_insertion = True
|
|
461
|
+
break
|
|
462
|
+
except:
|
|
463
|
+
pass
|
|
450
464
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
465
|
+
time.sleep(4)
|
|
466
|
+
code_insertion = False
|
|
467
|
+
for _ in range(30):
|
|
468
|
+
try:
|
|
469
|
+
# input('\n\n > Selecione o sistema e aperte alguma tecla.')
|
|
470
|
+
tools.find_element_with_wait(By.XPATH, f'{element_sistema}', timeout=1).send_keys(self.system)
|
|
471
|
+
time.sleep(1)
|
|
472
|
+
list_sistemas = tools.find_elements_with_wait(By.XPATH, '//div[contains(@role,"option")]')
|
|
473
|
+
if len(list_sistemas) == 1:
|
|
474
|
+
list_sistemas[0].click()
|
|
475
|
+
code_insertion = True
|
|
476
|
+
break
|
|
477
|
+
else:
|
|
478
|
+
mostrar_mensagem(
|
|
479
|
+
'Mais de um sistema encontrado, verifique o nome do sistema no WHOOM e coloque um nome único na função')
|
|
480
|
+
raise ValueError('Mais de um sistema encontrado, verifique o nome')
|
|
481
|
+
except:
|
|
482
|
+
pass
|
|
454
483
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
div_list[0].click()
|
|
484
|
+
if code_insertion:
|
|
485
|
+
break
|
|
458
486
|
|
|
459
|
-
|
|
487
|
+
if code_insertion:
|
|
488
|
+
tools.find_element_with_wait(By.XPATH, f"//button[contains(@data-testid,'submit') or contains(text(), 'Acessar')]").click()
|
|
489
|
+
print('Logado')
|
|
460
490
|
else:
|
|
461
|
-
|
|
462
|
-
div_text = div.find_element(By.XPATH, './span').text
|
|
463
|
-
if self.system.lower().strip() not in div_text.lower().strip():
|
|
464
|
-
div_list.remove(div)
|
|
465
|
-
|
|
466
|
-
if len(div_list) == 1:
|
|
467
|
-
div_list[0].click()
|
|
468
|
-
else:
|
|
469
|
-
mostrar_mensagem('Mais de um sistema encontrado, verifique o nome do sistema no WHOOM e coloque um nome único na função')
|
|
470
|
-
raise ValueError('Mais de um sistema encontrado, verifique o nome')
|
|
471
|
-
|
|
472
|
-
# Verifies if the system was opened
|
|
473
|
-
for _ in range(30):
|
|
474
|
-
time.sleep(1)
|
|
475
|
-
if len(self.driver.window_handles) == 1:
|
|
476
|
-
try:
|
|
477
|
-
tools.find_element_with_wait(By.XPATH, "//button[text()='Acessar']", timeout=1).click()
|
|
478
|
-
except:
|
|
479
|
-
time.sleep(1)
|
|
480
|
-
else:
|
|
481
|
-
time.sleep(3)
|
|
482
|
-
break
|
|
491
|
+
raise TimeoutError('Código WHOOM não chegou dentro do timeout estabelecido')
|
|
483
492
|
|
|
493
|
+
time.sleep(2)
|
|
484
494
|
self.driver.switch_to.window(self.driver.window_handles[-1])
|
|
485
495
|
attempt = 0
|
|
486
496
|
while 'whoom' in self.driver.title.strip().lower() and attempt <= 180:
|
|
497
|
+
if 'Sistema temporariamente indisponível. Tente novamente mais tarde.' in self.driver.page_source:
|
|
498
|
+
raise SystemError('Sistema indisponivel no momento.')
|
|
487
499
|
time.sleep(1)
|
|
488
500
|
attempt += 1
|
|
489
501
|
time.sleep(5)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: bcpkgfox
|
|
3
|
+
Version: 0.17.5
|
|
4
|
+
Summary: Biblioteca BCFOX
|
|
5
|
+
Home-page: https://github.com/robotsbcfox/PacotePythonBCFOX
|
|
6
|
+
Author: Guilherme Neri
|
|
7
|
+
Author-email: guilherme.neri@bcfox.com.br
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.6
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: setuptools
|
|
14
|
+
Requires-Dist: pyperclip
|
|
15
|
+
Requires-Dist: pyinstaller
|
|
16
|
+
Requires-Dist: selenium
|
|
17
|
+
Provides-Extra: capmonstercloudclient
|
|
18
|
+
Requires-Dist: capmonstercloudclient ; extra == 'capmonstercloudclient'
|
|
19
|
+
Provides-Extra: full
|
|
20
|
+
Requires-Dist: undetected-chromedriver ; extra == 'full'
|
|
21
|
+
Requires-Dist: webdriver-manager ; extra == 'full'
|
|
22
|
+
Requires-Dist: opencv-python ; extra == 'full'
|
|
23
|
+
Requires-Dist: pygetwindow ; extra == 'full'
|
|
24
|
+
Requires-Dist: pyinstaller ; extra == 'full'
|
|
25
|
+
Requires-Dist: screeninfo ; extra == 'full'
|
|
26
|
+
Requires-Dist: pyscreeze ; extra == 'full'
|
|
27
|
+
Requires-Dist: pyautogui ; extra == 'full'
|
|
28
|
+
Requires-Dist: selenium ; extra == 'full'
|
|
29
|
+
Requires-Dist: requests ; extra == 'full'
|
|
30
|
+
Requires-Dist: pymupdf ; extra == 'full'
|
|
31
|
+
Requires-Dist: Pillow ; extra == 'full'
|
|
32
|
+
Requires-Dist: psutil ; extra == 'full'
|
|
33
|
+
Requires-Dist: pynput ; extra == 'full'
|
|
34
|
+
Provides-Extra: psutil
|
|
35
|
+
Requires-Dist: psutil ; extra == 'psutil'
|
|
36
|
+
Provides-Extra: pynput
|
|
37
|
+
Requires-Dist: pynput ; extra == 'pynput'
|
|
38
|
+
Provides-Extra: pywinauto
|
|
39
|
+
Requires-Dist: pywinauto ; extra == 'pywinauto'
|
|
40
|
+
Provides-Extra: screeninfo
|
|
41
|
+
Requires-Dist: screeninfo ; extra == 'screeninfo'
|
|
42
|
+
Provides-Extra: twocaptcha
|
|
43
|
+
Requires-Dist: twocaptcha ; extra == 'twocaptcha'
|
|
44
|
+
Requires-Dist: 2captcha-python ; extra == 'twocaptcha'
|
|
45
|
+
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
bcpkgfox/__init__.py,sha256=49TPbTUNI6xKcYk4blwseUZQTgHtRcNI1AFEqxSQ3wY,16540
|
|
2
2
|
bcpkgfox/clean.py,sha256=80pJDTGmKmPiq73uL1IWopuxqVJF_bj_RVv-njkpl-A,8946
|
|
3
3
|
bcpkgfox/cli.py,sha256=E1Yahd8jIjUwxM6EMHveDDne5-fh8QeAvAhyATNatEo,33541
|
|
4
|
-
bcpkgfox/examples copy.py,sha256=EbiMy2mM1GT8juArugC9--pJzt0W20mIaJ7SuPGJvPE,9110
|
|
5
|
-
bcpkgfox/examples.py,sha256=gNKQBlONca0W81QHwUlnv_-J135dEj9IwBhCpmohMYw,5486
|
|
6
4
|
bcpkgfox/exec_file.py,sha256=fl_Do2SlF7JuXazpNTod-e_0WZUk355fbd7ustQvi40,3728
|
|
7
5
|
bcpkgfox/find_elements.py,sha256=oeB-73LqMLoKchozPXuxRkThBju9IgUKqbgU-2AAq0s,23027
|
|
8
6
|
bcpkgfox/get_driver.py,sha256=ohimk9E2hL6T35IXv0XX0uvWDGCUZvZDlPMnuRjV1R0,30490
|
|
9
|
-
bcpkgfox/invoke_api.py,sha256=
|
|
7
|
+
bcpkgfox/invoke_api.py,sha256=yxjAYCqZzoBNY_NPIX8Hc4e_dfpfCLk4ldaUoHxqiGE,20559
|
|
10
8
|
bcpkgfox/system.py,sha256=3lyOWx893T6KiAI-jDv7zAo3oKPf0Q5CLgZ8TeFd0Do,7901
|
|
11
|
-
bcpkgfox-0.17.
|
|
12
|
-
bcpkgfox-0.17.
|
|
13
|
-
bcpkgfox-0.17.
|
|
14
|
-
bcpkgfox-0.17.
|
|
15
|
-
bcpkgfox-0.17.
|
|
9
|
+
bcpkgfox-0.17.5.dist-info/METADATA,sha256=YW_ciYmPXgEoCzlYIbmc2CfTs0fPHv6frAfOeTSadsg,1725
|
|
10
|
+
bcpkgfox-0.17.5.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
|
|
11
|
+
bcpkgfox-0.17.5.dist-info/entry_points.txt,sha256=qmaEg6K7Y0HOeaFo-G6lf44InGkeVI4I6hqobcY_nns,653
|
|
12
|
+
bcpkgfox-0.17.5.dist-info/top_level.txt,sha256=h01SqyYBEfS72vkRFOlEDZBUSu9pzU0bdX4m9hWNNmw,9
|
|
13
|
+
bcpkgfox-0.17.5.dist-info/RECORD,,
|
bcpkgfox/examples copy.py
DELETED
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
'''
|
|
2
|
-
A grande maioria das classes e funções tem descrição explicando com detalhes o funcionamento e parametros
|
|
3
|
-
Para ver clicar na classe/função e apertar ctrl+K ctrl+I (VSCODE)
|
|
4
|
-
'''
|
|
5
|
-
import neri_library as nr # Só precisa de um import para
|
|
6
|
-
from neri_library import DK_ORANGE, ORANGE, GR, RD, RESET # Colors for terminal
|
|
7
|
-
|
|
8
|
-
# Default
|
|
9
|
-
import time
|
|
10
|
-
import sys
|
|
11
|
-
import os
|
|
12
|
-
|
|
13
|
-
class Browser():
|
|
14
|
-
def __init__(self):
|
|
15
|
-
super().__init__()
|
|
16
|
-
|
|
17
|
-
self.arguments = None
|
|
18
|
-
self.instance = None
|
|
19
|
-
self.browser = None
|
|
20
|
-
self.el = None
|
|
21
|
-
|
|
22
|
-
@staticmethod
|
|
23
|
-
def __simple_example():
|
|
24
|
-
'''
|
|
25
|
-
Aqui é só um exemplo de como é fácil iniciar um navegador com a lib.
|
|
26
|
-
Ja vem com configurações para evitar detecção e passar por captchas.
|
|
27
|
-
'''
|
|
28
|
-
Browser = nr.Instancedriver().initialize_driver()
|
|
29
|
-
Browser.get('URL SITE')
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def browser_iniciate(self):
|
|
33
|
-
'''
|
|
34
|
-
Aqui é um exemplo de driver em produção.
|
|
35
|
-
'''
|
|
36
|
-
print(f'{ORANGE} [ Inicializando Browser ] {RESET}')
|
|
37
|
-
|
|
38
|
-
# Inicia a instância do Navegador
|
|
39
|
-
self.instance = nr.Instancedriver(
|
|
40
|
-
Browser= 'Chrome',
|
|
41
|
-
# Browser="Firefox",
|
|
42
|
-
# Browser="edge",
|
|
43
|
-
# Browser="internet explorer",
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
# Inicia a instancia dos argumentos (opcional, não precisa por nenhum)
|
|
47
|
-
self.arguments = self.instance.arguments # Instância dos argumentos
|
|
48
|
-
|
|
49
|
-
# Fix: Abaixo alguns dos principais exemplos de argumento do selenium (tem todos)
|
|
50
|
-
# Exemplos de args para desligar indicadores de automação
|
|
51
|
-
self.arguments.add_experimental_option("excludeSwitches", ["enable-automation"])
|
|
52
|
-
self.arguments.add_experimental_option("useAutomationExtension", False)
|
|
53
|
-
self.arguments.add_argument("--disable-blink-features=AutomationControlled")
|
|
54
|
-
self.arguments.add_argument("--disable-blink-features")
|
|
55
|
-
self.arguments.add_argument("--disable-infobars")
|
|
56
|
-
self.arguments.add_argument("--disable-blink-features=AutomationControlled")
|
|
57
|
-
self.arguments.add_argument("--blink-settings=imagesEnabled=false")
|
|
58
|
-
|
|
59
|
-
# Exemplos de args para evitar detecção da automação nos sites e captchas
|
|
60
|
-
# Fix: Mas ja vem por padrão diversos argumentos tratando isso na função de 'initialize_driver'
|
|
61
|
-
self.arguments.add_argument("--disable-background-networking")
|
|
62
|
-
self.arguments.add_argument("--disable-sync")
|
|
63
|
-
self.arguments.add_argument("--disable-client-side-phishing-detection")
|
|
64
|
-
self.arguments.add_argument("--disable-popup-blocking")
|
|
65
|
-
self.arguments.add_argument("--disable-default-apps")
|
|
66
|
-
self.arguments.add_argument("--disable-features=IsolateOrigins,site-per-process")
|
|
67
|
-
self.arguments.add_argument("--disable-features=BlockInsecurePrivateNetworkRequests")
|
|
68
|
-
self.arguments.add_argument("--ignore-certificate-errors")
|
|
69
|
-
self.arguments.add_argument("--disable-gpu")
|
|
70
|
-
|
|
71
|
-
# Abaixo alguns exemplos para remover os logs do terminal (deixar mais limpo)
|
|
72
|
-
self.arguments.add_argument("--log-level=3")
|
|
73
|
-
self.arguments.add_experimental_option("excludeSwitches", ["enable-logging"])
|
|
74
|
-
self.arguments.add_experimental_option("useAutomationExtension", False)
|
|
75
|
-
|
|
76
|
-
# Exemplo de adicionar extensão (pega automático tanto pasta como .crx)
|
|
77
|
-
# self.instance.add_extensions('your_extension')
|
|
78
|
-
|
|
79
|
-
# Inicia o browser (driver)
|
|
80
|
-
self.browser = self.instance.initialize_driver(maximize=True)
|
|
81
|
-
|
|
82
|
-
# Instancia o 'finder', contém todas as funções de busca envolvendo o navegador
|
|
83
|
-
self.finder = self.instance.elements
|
|
84
|
-
|
|
85
|
-
class RPA_example(Browser):
|
|
86
|
-
def __init__(self):
|
|
87
|
-
super().__init__()
|
|
88
|
-
|
|
89
|
-
def open_site(self):
|
|
90
|
-
self.driver.get('https://github.com/NeriAzv')
|
|
91
|
-
|
|
92
|
-
self.cidade = cidade
|
|
93
|
-
self.pop_up_protection.start()
|
|
94
|
-
|
|
95
|
-
# Pesquisa
|
|
96
|
-
pesquisa = self.find_element_w(By.ID, 'searchGeneral')
|
|
97
|
-
time.sleep(1)
|
|
98
|
-
pesquisa.send_keys(cidade)
|
|
99
|
-
|
|
100
|
-
# Espera carregamento pesquisa
|
|
101
|
-
tempo = 0
|
|
102
|
-
while tempo < 30:
|
|
103
|
-
resultados = self.find_elements_w(By.XPATH, '//ul[@id="autocompleteSuggestions"]//li')
|
|
104
|
-
|
|
105
|
-
if resultados:
|
|
106
|
-
break
|
|
107
|
-
else:
|
|
108
|
-
time.sleep(1)
|
|
109
|
-
tempo += 1
|
|
110
|
-
|
|
111
|
-
# Resutaldos pesquisa
|
|
112
|
-
elemento_resultados_pesquisa = self.find_element_w(By.ID, 'autocompleteSuggestions')
|
|
113
|
-
soup = BeautifulSoup(elemento_resultados_pesquisa.get_attribute('outerHTML'), 'html.parser')
|
|
114
|
-
ul = soup.find('ul', id='autocompleteSuggestions')
|
|
115
|
-
|
|
116
|
-
cidades_extraidas = []
|
|
117
|
-
extrair = False
|
|
118
|
-
for tag in ul.find_all(recursive=False):
|
|
119
|
-
if tag.name == 'h6':
|
|
120
|
-
if 'Cidades' in tag.text:
|
|
121
|
-
extrair = True
|
|
122
|
-
continue
|
|
123
|
-
elif extrair:
|
|
124
|
-
break
|
|
125
|
-
|
|
126
|
-
if extrair and tag.name == 'li':
|
|
127
|
-
cidades_extraidas.append(tag)
|
|
128
|
-
|
|
129
|
-
if not cidades_extraidas:
|
|
130
|
-
raise Exception(f"{RED} > Cidade {cidade} não presente no site, verifique o nome. {RESET}")
|
|
131
|
-
|
|
132
|
-
# Eu poderia ter clicado no ultimo for, mas estou fazendo separado pegar todas as cidades e fazer um LOG mais organizado
|
|
133
|
-
for cidade_site in cidades_extraidas:
|
|
134
|
-
cidade_site_formatado = self.remover_acentos(cidade_site.text).lower()
|
|
135
|
-
cidade_user_formatado = self.remover_acentos(cidade).lower()
|
|
136
|
-
|
|
137
|
-
# Retorna em porcentagem quanto similar está com o nome do site (evita erros de usuários)
|
|
138
|
-
if cidade_site_formatado in cidade_site_formatado:
|
|
139
|
-
|
|
140
|
-
self.find_element_w(
|
|
141
|
-
By.XPATH,
|
|
142
|
-
f'//ul[@id="autocompleteSuggestions"]//li[normalize-space()="{cidade_site.text.strip()}"]'
|
|
143
|
-
).click()
|
|
144
|
-
|
|
145
|
-
return
|
|
146
|
-
|
|
147
|
-
raise Exception(f"{RED} > Cidade {cidade} não presente no site, verifique o nome. {RESET}")
|
|
148
|
-
|
|
149
|
-
def extrair_previsao(self) -> dict:
|
|
150
|
-
|
|
151
|
-
espera_site = 0
|
|
152
|
-
while espera_site <= 5:
|
|
153
|
-
|
|
154
|
-
try:
|
|
155
|
-
soup = BeautifulSoup(self.driver.page_source, "html.parser")
|
|
156
|
-
ul = soup.find("ul", class_="variables-list")
|
|
157
|
-
resultado_json = {
|
|
158
|
-
"cidade": self.cidade,
|
|
159
|
-
"temperatura_min": None,
|
|
160
|
-
"temperatura_max": None,
|
|
161
|
-
"condicao": None,
|
|
162
|
-
"umidade_min": None,
|
|
163
|
-
"umidade_max": None,
|
|
164
|
-
"vento": None,
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if not ul:
|
|
168
|
-
return resultado_json
|
|
169
|
-
|
|
170
|
-
for li in ul.find_all("li", class_="item"):
|
|
171
|
-
label = li.find("span", class_="variable").get_text(strip=True)
|
|
172
|
-
|
|
173
|
-
if label == "Temperatura":
|
|
174
|
-
spans = li.select("span.-gray-light")
|
|
175
|
-
min_txt = spans[0].get_text(strip=True)
|
|
176
|
-
max_txt = spans[1].get_text(strip=True)
|
|
177
|
-
resultado_json["temperatura_min"] = min_txt if min_txt.endswith("°") else min_txt + "°"
|
|
178
|
-
resultado_json["temperatura_max"] = max_txt if max_txt.endswith("°") else max_txt + "°"
|
|
179
|
-
|
|
180
|
-
elif label == "Umidade":
|
|
181
|
-
spans = li.select("span.-gray-light")
|
|
182
|
-
resultado_json["umidade_min"] = spans[0].get_text(strip=True)
|
|
183
|
-
resultado_json["umidade_max"] = spans[1].get_text(strip=True)
|
|
184
|
-
|
|
185
|
-
elif label == "Vento":
|
|
186
|
-
texto = li.find("div", class_="_flex").get_text(separator=" ", strip=True)
|
|
187
|
-
texto_limpo = " ".join(texto.split())
|
|
188
|
-
resultado_json["vento"] = texto_limpo.replace("Vento", "", 1).strip()
|
|
189
|
-
|
|
190
|
-
elif label == "Sol":
|
|
191
|
-
nasc, _, pst = li.find("span", recursive=False).get_text(strip=True).partition(" ")
|
|
192
|
-
resultado_json["condicao"] = f"{nasc} {pst}"
|
|
193
|
-
|
|
194
|
-
return resultado_json
|
|
195
|
-
|
|
196
|
-
except:
|
|
197
|
-
time.sleep(1)
|
|
198
|
-
espera_site +=1
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
class Logs:
|
|
203
|
-
''' Server somente para impressão de resultados, não afeta o funcionamento do robo '''
|
|
204
|
-
def imprimir_logs(self, log_resultado: dict):
|
|
205
|
-
if not log_resultado:
|
|
206
|
-
return
|
|
207
|
-
|
|
208
|
-
print(f"\n{BOLD}{BLUE} {log_resultado.get('cidade', '').title()}:{RESET}")
|
|
209
|
-
|
|
210
|
-
# Itera sobre o dict
|
|
211
|
-
for chave, valor in log_resultado.items():
|
|
212
|
-
if chave == "cidade":
|
|
213
|
-
continue
|
|
214
|
-
print(f" - {BLUE}{chave.capitalize()}:{RESET} {valor}")
|
|
215
|
-
|
|
216
|
-
def main():
|
|
217
|
-
|
|
218
|
-
# Instâncias
|
|
219
|
-
br = Browser()
|
|
220
|
-
rpa = RPA_example()
|
|
221
|
-
|
|
222
|
-
br.browser_iniciate()
|
|
223
|
-
rpa.open_site()
|
|
224
|
-
|
|
225
|
-
if __name__ == "__main__":
|
|
226
|
-
print(f'{DK_ORANGE} [ Robo Iniciado ] {RESET}')
|
|
227
|
-
main()
|
bcpkgfox/examples.py
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
# FIX: Driver
|
|
3
|
-
# region Driver
|
|
4
|
-
"""
|
|
5
|
-
Example of how easy is start the driver.
|
|
6
|
-
|
|
7
|
-
It automatically configure the driver with stealth settings to pass over the captchas.
|
|
8
|
-
It also automatically prevents a various bugs like versions incompatibles and others.
|
|
9
|
-
"""
|
|
10
|
-
import neri_library as nr
|
|
11
|
-
|
|
12
|
-
# To choose the browser just change the name
|
|
13
|
-
driver = nr.Instancedriver(
|
|
14
|
-
Browser="chrome"
|
|
15
|
-
# Browser="Firefox"
|
|
16
|
-
# Browser="edge"
|
|
17
|
-
# Browser="internet explorer"
|
|
18
|
-
).initialize_driver()
|
|
19
|
-
|
|
20
|
-
driver.get("https://www.google.com")
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
# FIX: Driver Options
|
|
25
|
-
# region Driver Options
|
|
26
|
-
"""
|
|
27
|
-
You can also use arguments to configure the driver manually
|
|
28
|
-
"""
|
|
29
|
-
|
|
30
|
-
import neri_library as nr
|
|
31
|
-
|
|
32
|
-
instance = nr.Instancedriver(Browser="chrome")
|
|
33
|
-
instance.initialize_options() # Iniciate the options mode
|
|
34
|
-
|
|
35
|
-
# Here you can add as many as you want
|
|
36
|
-
instance.arguments.add_new_argument("--headless") # Example
|
|
37
|
-
instance.arguments.add_experimental_option("useAutomationExtension", False) # Example
|
|
38
|
-
instance.arguments.add_experimental_options("excludeSwitches", ["enable-automation"]) # Example
|
|
39
|
-
|
|
40
|
-
# You can add a extension with one line too (already have 'resourse path')
|
|
41
|
-
instance.add_extension("path/to/extension.crx")
|
|
42
|
-
|
|
43
|
-
driver = instance.initialize_driver()
|
|
44
|
-
driver.get("https://www.google.com")
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
# FIX: Selenoid
|
|
49
|
-
# region Selenoid
|
|
50
|
-
"""
|
|
51
|
-
Functions of selenoid (docker)
|
|
52
|
-
|
|
53
|
-
The driver comes already configured to run in selenoid, but you can also configure it manually.
|
|
54
|
-
"""
|
|
55
|
-
|
|
56
|
-
import neri_library as nr
|
|
57
|
-
|
|
58
|
-
instance = nr.Instancedriver(Browser="chrome", Selenoid=True)
|
|
59
|
-
|
|
60
|
-
# Example if you wanna to customize
|
|
61
|
-
instance.Selenoid.add_capabilities("enableVNC", True) # Example
|
|
62
|
-
instance.Selenoid.add_capabilities("versiion", "122.0") # Example
|
|
63
|
-
|
|
64
|
-
driver = instance.initialize_driver()
|
|
65
|
-
driver.get("https://www.google.com")
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
# FIX: Elements
|
|
70
|
-
#region Elements
|
|
71
|
-
"""
|
|
72
|
-
Some features of selenium that i improve to prevents bugs and work correctly.
|
|
73
|
-
|
|
74
|
-
(you only need import the neri_library)
|
|
75
|
-
"""
|
|
76
|
-
import neri_library as nr
|
|
77
|
-
from neri_library import By # Optional to imitating selenium, you can use 'xpath' in place of By.XPATH for example
|
|
78
|
-
|
|
79
|
-
instance = nr.Instancedriver()
|
|
80
|
-
driver = instance.initialize_driver()
|
|
81
|
-
finder = instance.elements
|
|
82
|
-
|
|
83
|
-
# Selenium searchers
|
|
84
|
-
example = finder.find_element_with_wait(By.XPATH, '/your/xpath/here') # Have too XPATH, CSS, NAME, ID...
|
|
85
|
-
example_list = finder.find_elements_with_wait(By.XPATH, '/this/brings/a/list') # work same as the fn above (this have a 's' in the name)
|
|
86
|
-
|
|
87
|
-
# Selenium interactions works normally too
|
|
88
|
-
finder.find_element_with_wait(By.XPATH, '/elmt/xpath').send_keys('')
|
|
89
|
-
finder.find_element_with_wait(By.NAME, 'elmt_name').clear()
|
|
90
|
-
finder.find_element_with_wait(By.ID, 'elmt_id').click()
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
# FIX: Elemets created
|
|
95
|
-
#region Creations
|
|
96
|
-
"""
|
|
97
|
-
Below some functions that i created for web scraping
|
|
98
|
-
"""
|
|
99
|
-
import neri_library as nr
|
|
100
|
-
from neri_library import By
|
|
101
|
-
|
|
102
|
-
instance = nr.Instancedriver()
|
|
103
|
-
driver = instance.initialize_driver()
|
|
104
|
-
finder = instance.elements
|
|
105
|
-
|
|
106
|
-
# Just a example to uso on the functions below
|
|
107
|
-
example_element = finder.find_element_with_wait(By.XPATH, '/example')
|
|
108
|
-
|
|
109
|
-
'''
|
|
110
|
-
This function moves the mouse to an element imitating human behavior, to avoid captchas.
|
|
111
|
-
With some deviations and inaccuracies on the way to the destination (like a human).
|
|
112
|
-
( It use a external UI methods, so the browser can't detect )
|
|
113
|
-
'''
|
|
114
|
-
finder.move_mouse_smoothly(
|
|
115
|
-
element = example_element,
|
|
116
|
-
pure = True, # Pure is to you pass the cordinates instead the element
|
|
117
|
-
click = False,
|
|
118
|
-
x_adittional = 100, # Here you can add a number on cordinates (if the elements is bugged)
|
|
119
|
-
y_adittional = 100
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
# Find a image in the screen (you can pass a screenshot of a element)
|
|
123
|
-
finder.move_to_image(
|
|
124
|
-
'img_path.png', # You can send a list to search for more than one
|
|
125
|
-
click_on_final = True,
|
|
126
|
-
trail = True, # Move your mouse using 'move_mouse_smoothly' above (if False will teleport you mouse)
|
|
127
|
-
verify = True, # Just verify if the image is on the screen (Deactivates the 'trail' and 'click')
|
|
128
|
-
tolerancia = 0.8, # Deviation tolerance of the found image (0.8 = 80%)
|
|
129
|
-
timeout = 10, # The time that function will search the image(s)
|
|
130
|
-
repeat = True # It deactivates the 'timeout'
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
# It will respect the timeout ignoring the "ClickInterrupted" errors
|
|
134
|
-
finder.wait_for_element_be_clickable(By.CLASS_NAME, 'elmt_class', timeout=10)
|
|
135
|
-
|
|
136
|
-
# It is a 'driver.execute_script' of the selenium, but with a timeout
|
|
137
|
-
finder.script_console_with_wait('Returns element.value', timeout = 10)
|
|
138
|
-
|
|
139
|
-
'''
|
|
140
|
-
You can use this function below to wait for a image, window, element or text.
|
|
141
|
-
'''
|
|
142
|
-
finder.wait_for_appear(
|
|
143
|
-
object = '', # title_window / img_path / text / element
|
|
144
|
-
type = '', # window / image / text / element (here you really write the type)
|
|
145
|
-
timeout = 10
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
finder.wait_for_appear( # finder.wait_for_appear( # finder.wait_for_appear( # finder.wait_for_appear(
|
|
149
|
-
object = 'Window title', # object = 'C://image_path', # object = 'Site Text', # object = '/xpath/',
|
|
150
|
-
type = 'window', # type = 'image', # type = 'text', # type = 'element',
|
|
151
|
-
timeout = 10 # timeout = 10 # timeout = 10 # timeout = 10
|
|
152
|
-
) # ) # ) # )
|
|
153
|
-
finder.wait_for_disappear() # Same thing
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: bcpkgfox
|
|
3
|
-
Version: 0.17.4
|
|
4
|
-
Summary: Biblioteca BCFOX
|
|
5
|
-
Home-page: https://github.com/robotsbcfox/PacotePythonBCFOX
|
|
6
|
-
Author: Guilherme Neri
|
|
7
|
-
Author-email: guilherme.neri@bcfox.com.br
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
-
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Python: >=3.6
|
|
12
|
-
Description-Content-Type: text/markdown
|
|
13
|
-
Requires-Dist: setuptools
|
|
14
|
-
Requires-Dist: pyperclip
|
|
15
|
-
Requires-Dist: pyinstaller
|
|
16
|
-
Requires-Dist: selenium
|
|
17
|
-
Provides-Extra: pynput
|
|
18
|
-
Requires-Dist: pynput; extra == "pynput"
|
|
19
|
-
Provides-Extra: screeninfo
|
|
20
|
-
Requires-Dist: screeninfo; extra == "screeninfo"
|
|
21
|
-
Provides-Extra: pywinauto
|
|
22
|
-
Requires-Dist: pywinauto; extra == "pywinauto"
|
|
23
|
-
Provides-Extra: capmonstercloudclient
|
|
24
|
-
Requires-Dist: capmonstercloudclient; extra == "capmonstercloudclient"
|
|
25
|
-
Provides-Extra: twocaptcha
|
|
26
|
-
Requires-Dist: twocaptcha; extra == "twocaptcha"
|
|
27
|
-
Requires-Dist: 2captcha-python; extra == "twocaptcha"
|
|
28
|
-
Provides-Extra: psutil
|
|
29
|
-
Requires-Dist: psutil; extra == "psutil"
|
|
30
|
-
Provides-Extra: full
|
|
31
|
-
Requires-Dist: undetected-chromedriver; extra == "full"
|
|
32
|
-
Requires-Dist: webdriver-manager; extra == "full"
|
|
33
|
-
Requires-Dist: opencv-python; extra == "full"
|
|
34
|
-
Requires-Dist: pygetwindow; extra == "full"
|
|
35
|
-
Requires-Dist: pyinstaller; extra == "full"
|
|
36
|
-
Requires-Dist: screeninfo; extra == "full"
|
|
37
|
-
Requires-Dist: pyscreeze; extra == "full"
|
|
38
|
-
Requires-Dist: pyautogui; extra == "full"
|
|
39
|
-
Requires-Dist: selenium; extra == "full"
|
|
40
|
-
Requires-Dist: requests; extra == "full"
|
|
41
|
-
Requires-Dist: pymupdf; extra == "full"
|
|
42
|
-
Requires-Dist: Pillow; extra == "full"
|
|
43
|
-
Requires-Dist: psutil; extra == "full"
|
|
44
|
-
Requires-Dist: pynput; extra == "full"
|
|
45
|
-
Dynamic: author
|
|
46
|
-
Dynamic: author-email
|
|
47
|
-
Dynamic: classifier
|
|
48
|
-
Dynamic: description-content-type
|
|
49
|
-
Dynamic: home-page
|
|
50
|
-
Dynamic: provides-extra
|
|
51
|
-
Dynamic: requires-dist
|
|
52
|
-
Dynamic: requires-python
|
|
53
|
-
Dynamic: summary
|
|
File without changes
|
|
File without changes
|