├── .gitignore
├── LICENSE
├── README.md
├── automatizacao_edp.py
├── consult_folder.py
├── create_folder.py
├── download_files.py
├── ftp_server.py
├── img
├── capa_video_automatizacao_python.cdr
└── capa_video_automatizacao_python.png
├── language.py
├── move_files.py
├── parameters.py
├── security.py
├── selenium_webdriver
├── Leia-me.txt
├── chromedriver.exe
└── chromedriver_win32.zip
└── unzip_files.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Marquescharlon Santos
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Realizar login no site, baixar e descompactar arquivos
2 |
3 | O que fazer quando a empresa não disponibilizar uma API para você poder consumir?
4 | Após alguns dias pesquisando e avaliando as alternativas de como automatizar esse processo, me deparei com Selenium, uma biblioteca poderosa. Com ela é possível realizar autenticação, ações como: navegar no site e baixar arquivos. E é o que essa automatização se propõe a fazer.
5 |
6 | ### Assista o vídeo que você terá uma visão melhor deste projeto:
7 |
8 | [](https://youtu.be/DkMk85ZxW-k)
9 |
10 | ## Parâmetros
11 | Vou destacar aqui os parâmetros principais, os que conversam diretamente com o Selenium. Para isso, acesse o arquivo ```parameters.py```
12 |
13 | Para definir o endereço do site basta atribuí-lo na variável ```link=''```.
14 | Se o endereço da página onde os arquivos estiverem for fixo poderá definí-lo em ```page_files=''```
15 |
16 | > Como foi o meu caso, não precisei navegar clicando em diferentes menus até chegar no endereço, mas se precisar, também é possível adaptar conforme sua necessidade.
17 |
18 | ## Configurar as dependências do Selenium
19 |
20 | Para permitir realizar o acesso e a navegação pelo navegador através do Selenium se faz necessário baixar **chromedriver_win32.zip**, lembrando que você deverá baixar para o seu navegador em específico caso não seja o Google Chrome. Para mais informações acesse a documentação do [Selenium](https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/install_drivers/)
21 |
22 | a) Acessar o endereço https://chromedriver.chromium.org/downloads e baixar o arquivo conforme a versão do seu browser. Para saber qual a versão baixar é simples, abra o Google Chrome e vá em ```Configurações > Sobre o Google Chrome```.
23 |
24 | b) Descompactar o arquivo **chromedriver_win32.zip**
25 | c) Copiar o seu conteúdo para dentro da pasta raiz do Python ```C:\WebScraping-Selenium-Python\selenium_webdriver\```
26 |
27 | > Outro passo importante é criar um path em variáveis de ambiente, também é simples, só seguir os próximos passos.
28 |
29 | d) Clicar com botão direito em **Este Computador / Meu Computador**
30 | e) Clicar em Configurações avançadas do sistema
31 | f) Clicar em **Variáveis de Ambiente**
32 | g) Selecionar **Path** e clicar em Editar
33 | h) Clicar em Novo
34 | i) Adicionar o caminho onde colocou o **chromedriver.exe**
35 |
36 | ## Bibliotecas utilizadas
37 |
38 | ```os.path```
39 | ```pathlib```
40 | ```selenium```
41 | ```time```
42 | ```ftplib```
43 | ```sys```
44 | ```os```
45 | ```pyodbc```
46 | ```datetime```
47 | ```bs4```
48 | ```zipfile```
49 | ```pyinstaller```
50 |
51 | ## Etapas implementadas
52 |
53 | - [x] Acessar o site e realizar o login
54 | - [x] Direcionar até o destino onde estão os arquivos a serem baixados
55 | - [x] Adicionar condição para baixar os arquivos corretos por meio do xPath
56 | - [x] Criar diretório temporário Temp e Duplicados para manipulação dos arquivos
57 | - [x] Validar se a quantidade baixada corresponde a quantidade que foi feito download do site
58 | - [x] Descompactar arquivos .ZIP
59 | - [x] Mover arquivos para a pasta de destino C:\Concessionária\Retorno\
60 | - [x] Registrar log dos arquivos a serem copiados para o servidor
61 | - [x] Copiar arquivos para o servidor
62 | - [x] Realizar também uma cópia para a pasta C:\Concessionária\Retorno\Baixados\
63 | - [x] Excluir arquivos que foram copiados com sucesso da pasta C:\Concessionária\Retorno\
64 | - [x] Adaptar para que seja possível executar para mais de um usuário
65 | - [x] Enviar log via E-mail
66 |
67 | ## Gerar executável
68 |
69 | Primeiro será necessário instalar a biblioteca PyInstaller que será responsável por gerar esse arquivo .exe:
70 | ```
71 | pip install PyInstaller
72 | ```
73 | Agora, só acessar a raiz de seu projeto e executar o seguinte comando:
74 | ```
75 | pyinstaller --onefile --noconsole automatizacao_edp.py
76 | ```
77 |
78 | Se utiliza alguma biblioteca sua ou de terceiros será necessário usar o seguinte comando **--paths=../** para gerar o executável.
79 |
80 | ```
81 | pyinstaller --onefile --noconsole --paths=../ automatizacao_edp.py
82 | ```
83 |
84 | > Lembrando que automatizacao_edp.py é o nome do arquivo principal, por isso, é informado na hora de gerar o executável.
85 |
86 | # Conclusão
87 |
88 | Essa automatização se fez necessária com a grande demanda de atividades diárias que foram surgindo, a necessidade de diariamente ter que acessar um determinado site e baixar os arquivos de retorno que não poderiam deixar de serem lidos. Fazer esse processo manualmente acaba expondo a erros e consequentemente no desperdício de recursos. Além disso, conversa diretamente com o clientecentrismo, quando podemos diminuir as falhas e agilizar os processos de baixas de suas mensalidades evitando qualquer desconforto no bloqueio dos serviços.
89 |
--------------------------------------------------------------------------------
/automatizacao_edp.py:
--------------------------------------------------------------------------------
1 |
2 | import download_files
3 | import ftp_server
4 |
5 | def main() -> None:
6 |
7 | download_files.download('Bandeirante')
8 | download_files.download('ESCELSA')
9 |
10 | ftp_server.copy_70('Bandeirante')
11 | ftp_server.copy_70('ESCELSA')
12 |
13 | if __name__ == '__main__':
14 | main()
--------------------------------------------------------------------------------
/consult_folder.py:
--------------------------------------------------------------------------------
1 | import os.path
2 | import parameters as p
3 |
4 | def result_qtd(source_folder, file_begin, file_end):
5 | list_files = os.listdir(source_folder)
6 |
7 | qtd_file = 0
8 |
9 | for file in list_files:
10 | if file_end in file:
11 | if file_begin in file:
12 | qtd_file += 1
13 |
14 | return qtd_file
15 |
16 | def result_file(source_folder):
17 | list_files = os.listdir(source_folder)
18 | return list_files
19 |
20 | def duplicate_qtd(source_folder,identify_duplicate, identify_duplicate_final):
21 | list_files = os.listdir(source_folder)
22 |
23 | qtd_file = 0
24 |
25 | for file in list_files:
26 | if identify_duplicate in file:
27 | if identify_duplicate_final in file:
28 | qtd_file += 1
29 |
30 | return qtd_file
31 |
32 | def await_file(source_folder, file_begin, file_end):
33 | list_files = os.listdir(source_folder)
34 |
35 | qtd_file = 0
36 |
37 | for file in list_files:
38 | if file_begin in file:
39 | if file_end in file:
40 | qtd_file+=1
41 | return qtd_file
42 |
43 |
44 | if __name__ == '__main__':
45 |
46 | concessionaria = 'Bandeirante'
47 |
48 | print(
49 | duplicate_qtd(
50 | p.downloads_folder,
51 | p.identify_file(concessionaria, 'begin', duplicate=True),
52 | p.identify_file(concessionaria, 'end', duplicate=True)
53 | )
54 | )
55 |
56 | print(
57 | result_qtd(
58 | p.downloads_folder,
59 | p.identify_file(concessionaria, 'begin'),
60 | p.identify_file(concessionaria, 'end')
61 | )
62 | )
63 |
64 | print(await_file(
65 | p.downloads_folder,
66 | p.identify_file(concessionaria, 'begin'),
67 | ".ZIP.crdownload"
68 | ))
--------------------------------------------------------------------------------
/create_folder.py:
--------------------------------------------------------------------------------
1 | import os.path
2 | import language
3 | from pathlib import Path
4 |
5 | def create_folder(folder_local:str='', folder_name:str=''):
6 |
7 | """
8 | folder_local='Downloads', 'Documentos', 'Imagens' ou 'Videos' \n
9 | folder_name='TESTE' \n
10 | folder_name='TESTE/Subpasta'
11 | """
12 |
13 | def folder_name_local(folder_local):
14 | folder_ = language.translation(folder_local)
15 | return folder_
16 |
17 | folder_path = os.path.expanduser(rf"~\{folder_name_local(folder_local)}")
18 |
19 | print(folder_path)
20 |
21 | def folder_mount(folder_path, folder_name):
22 | print(folder_name)
23 |
24 | _path = folder_path
25 | _path = os.path.join(rf'{_path}',folder_name)
26 | print(_path)
27 | if Path(_path).is_dir():
28 | print("Diretório '%s' já existe." %_path)
29 | try:
30 | os.makedirs(_path)
31 | except FileExistsError as erro:
32 | print(erro)
33 |
34 | folder_mount(folder_path, folder_name)
35 |
36 |
37 | if __name__ == '__main__':
38 |
39 | create_folder("Documentos", "EDP/Temp/Duplicados")
--------------------------------------------------------------------------------
/download_files.py:
--------------------------------------------------------------------------------
1 | from selenium import webdriver
2 | from selenium.webdriver.chrome.options import Options
3 | from time import sleep
4 | from bs4 import BeautifulSoup
5 | import security as pw
6 | import pandas as pd
7 | import create_folder as cf
8 | import move_files as mf
9 | import consult_folder
10 | import parameters as p
11 | import unzip_files
12 |
13 | def download(concessionaria:str=''):
14 |
15 | """
16 | Informar o nome da concessionária: concessionaria=''
17 | """
18 |
19 | username_field = pw.user(concessionaria, 'User')
20 | password_field = pw.user(concessionaria, 'Password')
21 |
22 | options = Options()
23 | # options.add_argument("--headless")
24 | options.add_argument('--no-sandbox')
25 | options.add_argument('--disable-gpu') # usado apenas no windows
26 | # options.add_argument('start-maximized')
27 | options.add_argument('disable-infobars')
28 | options.add_argument("--disable-extensions")
29 | navegador = webdriver.Chrome(p.executable_path, chrome_options=options)
30 | navegador.minimize_window()
31 | navegador.get(url=p.link)
32 | print ("Headless Chrome Initialized on Windows OS")
33 |
34 | # Por questões de segurança algumas informações foram excluídas como xPath
35 | # Nota que o xPath não é simplesmente '//*[@id=""]', ele possui mais informações dentro das ""
36 |
37 | input_email = navegador.find_element("xpath", '//*[@id=""]')
38 | input_email.send_keys(username_field)
39 |
40 | input_password = navegador.find_element("xpath", '//*[@id=""]')
41 | input_password.send_keys(password_field)
42 |
43 | button_enter = navegador.find_element("xpath", '//*[@id=""]')
44 | button_enter.click()
45 |
46 | navegador.get(p.page_files)
47 |
48 | qtd_site = 0
49 |
50 | def get_FezDownload(line):
51 | xpath = '//*[@id="TableIndex"]/tbody/tr['+line+']'
52 | file = navegador.find_element("xpath", xpath)
53 | html_returns = file.get_attribute('innerHTML')
54 | records = BeautifulSoup(html_returns, 'html.parser')
55 | for row in records.find_all("td", attrs={"class": "text-center"}):
56 | x = row.text
57 | x = ''.join(filter(str.isalnum, x))
58 | if x == "Sim":
59 | return 1
60 | if x == "Não":
61 | return 0
62 |
63 | file_df = {'file_name': []}
64 | file_df = pd.DataFrame(file_df)
65 |
66 | for i in range(10):
67 | line = str(i+1)
68 | xpath = '//*[@id="TableIndex"]/tbody/tr['+line+']/td[1]/a'
69 | file = navegador.find_element("xpath", xpath)
70 |
71 | soup = BeautifulSoup(file.text, 'html.parser')
72 | file_df.loc[i] = [str(soup)]
73 |
74 | if get_FezDownload(line) == 0:
75 | file.click()
76 | qtd_site += 1
77 |
78 | cf.create_folder("Documentos", "EDP/Temp")
79 | cf.create_folder("Documentos", "EDP/Temp/Duplicados")
80 |
81 | files_folder_ = consult_folder.result_qtd(
82 | p.downloads_folder,
83 | p.identify_file(concessionaria, 'begin'),
84 | p.identify_file(concessionaria, 'end')
85 | )
86 |
87 | duplicate_qtd = consult_folder.duplicate_qtd(
88 | p.downloads_folder,
89 | p.identify_file(concessionaria, 'begin', duplicate=True),
90 | p.identify_file(concessionaria, 'end', duplicate=True)
91 | )
92 |
93 | qtd_site -= duplicate_qtd
94 |
95 | await_file_ = consult_folder.await_file(
96 | p.downloads_folder,
97 | p.identify_file(concessionaria, 'begin'),
98 | ".ZIP.crdownload"
99 | )
100 |
101 | if files_folder_ >= qtd_site:
102 | if await_file_ >= 1:
103 | sleep(15)
104 | mf.move_files(
105 | p.downloads_folder,
106 | p.identify_file(concessionaria, 'begin'),
107 | p.identify_file(concessionaria, 'end'),
108 | p.temp_folder,
109 | qtd_site
110 | )
111 | mf.move_files_duplicates(
112 | p.downloads_folder,
113 | p.identify_file(concessionaria, 'begin', duplicate=True),
114 | p.identify_file(concessionaria, 'end', duplicate=True),
115 | p.temp_duplicados
116 | )
117 | unzip_files.files(
118 | p.temp_folder,
119 | p.identify_file(concessionaria, 'begin'),
120 | p.identify_file(concessionaria, 'end'),
121 | delete_file=True
122 | )
123 | mf.move_files(
124 | p.temp_folder,
125 | p.identify_file(concessionaria, 'begin', unzip=True),
126 | p.identify_file(concessionaria, 'end', unzip=True),
127 | p.return_folder(concessionaria)
128 | )
129 |
130 | navegador.quit()
131 |
132 | if __name__ == '__main__':
133 |
134 | download('Bandeirantes')
135 | download('ESCELSA')
136 |
--------------------------------------------------------------------------------
/ftp_server.py:
--------------------------------------------------------------------------------
1 | from ftplib import FTP
2 | import security as pw
3 | import sys
4 | import os
5 | import parameters as p
6 | sys.path.insert(0, 'C:\\Repositorios\\Projetos_Python\\')
7 | import function_models.function_models as fm
8 |
9 | ftp_70 = FTP()
10 |
11 | # Evite adicionar senha aqui
12 | # Se adicionado no arquivo security.py você poderá chamá-lo assim como fiz aqui
13 |
14 | def copy_70(concessionaria):
15 |
16 | global str_log
17 | str_log = ""
18 |
19 | folder_136 = f'C:\\{concessionaria}\\Retorno\\'
20 | path_70 = f'/Cobranca/{concessionaria}/Retorno'
21 |
22 | try:
23 | ftp_70.connect(pw.ftp70_host, pw.ftp70_porta)
24 | ftp_70.login(pw.ftp70_username, pw.ftp70_password)
25 | ftp_70.encoding = 'utf-8'
26 | str_log += fm.LogMensagem('C_SFTP',servidor=pw.ftp70_host)
27 | ftp_70.nlst()
28 |
29 | ftp_70.cwd(f'/Cobranca/{concessionaria}/Retorno')
30 |
31 | list_files = os.listdir(folder_136)
32 |
33 | qtd_file = 0
34 |
35 | for file in list_files:
36 | if '.TXT' in file:
37 | fileObject = open(folder_136 + file, 'rb')
38 | ftp_70.storlines('STOR ' + file, fileObject)
39 | ftp_70.retrbinary('RETR ' + file,
40 | open(folder_136 + 'Baixados\\' + file, 'wb').write)
41 | fileObject.close()
42 |
43 | str_log += fm.LogMensagem('SCA',filename=file,servidor=p.folder_70 + path_70)
44 | qtd_file+=1
45 |
46 | if os.path.exists(folder_136 + file):
47 | os.remove(folder_136 + file)
48 |
49 | if qtd_file == 0:
50 | str_log += fm.LogMensagem(tipo='P', mensagem='Site verificado, porém, nenhum retorno para ser baixado.')
51 |
52 | fm.EnviaEmail(destinatario=pw.email_cobranca, assunto_email='Log Retorno ' + concessionaria, modelo_html='', mensagem=str_log,
53 | cabecalho=True, titulo_cabecalho=concessionaria)
54 |
55 | except Exception as ex:
56 | str_log += fm.LogMensagem('E_SFTP',servidor=pw.ftp70_host,erro=ex)
57 |
58 | if __name__ == '__main__':
59 |
60 | copy_70('Bandeirante')
61 | copy_70('ESCELSA')
--------------------------------------------------------------------------------
/img/capa_video_automatizacao_python.cdr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marquescharlon/Automatizacao-Selenium-Python/4ded05350eaf8bb11ac953125dcd3493cbc310a3/img/capa_video_automatizacao_python.cdr
--------------------------------------------------------------------------------
/img/capa_video_automatizacao_python.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marquescharlon/Automatizacao-Selenium-Python/4ded05350eaf8bb11ac953125dcd3493cbc310a3/img/capa_video_automatizacao_python.png
--------------------------------------------------------------------------------
/language.py:
--------------------------------------------------------------------------------
1 |
2 | def translation(folder):
3 | if folder == "Downloads":
4 | return "Downloads"
5 | elif folder == "Documentos" or folder == "Documents":
6 | return "Documents"
7 | elif folder == "Imagens" or folder == "Pictures":
8 | return "Pictures"
9 | elif folder == "Videos":
10 | return "Videos"
11 | else:
12 | return folder
--------------------------------------------------------------------------------
/move_files.py:
--------------------------------------------------------------------------------
1 | from contextlib import nullcontext
2 | import os.path
3 | from pathlib import Path
4 | import consult_folder
5 | import parameters as p
6 |
7 | def move_files(source_folder:str='', file_begin:str='', file_end:str='', destination_folder:str='', qtd_site=0):
8 |
9 | """
10 | Pasta onde se encontram os arquivos: source_folder='' \n
11 | Pasta Downloads: p.downloads_folder \n
12 | Pasta Temp: p.temp_folder \n
13 | Pasta Temp/Duplicados: p.temp_duplicados \n
14 | Ou a pasta de retorno: return_folder(concessionaria) \n
15 | Pesquisar pelo início do arquivo: file_begin='' \n
16 | p.identify_file(concessionaria, 'begin') \n
17 | p.identify_file(concessionaria, 'begin', duplicate=True) \n
18 | p.identify_file(concessionaria, 'begin', unzip=True) \n
19 | Pesquisar pelo final do arquivo: file_end='' \n
20 | p.identify_file(concessionaria, 'end') \n
21 | p.identify_file(concessionaria, 'end', duplicate=True) \n
22 | p.identify_file(concessionaria, 'end', unzip=True) \n
23 | Pasta de destino: destination_folder='' \n
24 | Verificar se a quantidade baixada é o mesmo que consta na pasta: qtd_site=''
25 | """
26 |
27 | qtd_site_ = qtd_site
28 |
29 | files_folder = consult_folder.result_qtd(source_folder, file_begin, file_end)
30 | qtd_files_folder = 0
31 |
32 | list_files = consult_folder.result_file(source_folder)
33 |
34 | if qtd_site_ != 0:
35 |
36 | if int(qtd_site) != int(files_folder):
37 | qtd_files_folder = files_folder
38 |
39 | while qtd_site > qtd_files_folder:
40 | qtd_files_folder = 0
41 | for file in list_files:
42 | if file_begin in file:
43 | if file_end in file:
44 | print(file)
45 | qtd_files_folder += 1
46 | list_files = consult_folder.result_file(source_folder)
47 |
48 | if int(qtd_site) == int(qtd_files_folder) or int(qtd_site) == int(files_folder):
49 | list_files = os.listdir(source_folder)
50 | print(list_files)
51 | for file in list_files:
52 | if file_begin in file:
53 | if file_end in file:
54 | try:
55 | if os.path.exists(f"{destination_folder}/{file}"):
56 | os.remove(f"{destination_folder}/{file}")
57 | os.rename(f"{source_folder}/{file}", f"{destination_folder}/{file}")
58 | except FileNotFoundError as erro:
59 | print(erro)
60 | except TypeError as erro:
61 | print(erro)
62 | except Exception as erro:
63 | print("Ocorreu um erro diferente dos que já foram tratados ao tentar mover arquivo(s)")
64 | else:
65 | list_files = os.listdir(source_folder)
66 | for file in list_files:
67 | if file_begin in file:
68 | if file_end in file:
69 | try:
70 | if os.path.exists(f"{destination_folder}/{file}"):
71 | os.remove(f"{destination_folder}/{file}")
72 | os.rename(f"{source_folder}/{file}", f"{destination_folder}/{file}")
73 | except FileNotFoundError as erro:
74 | print(erro)
75 | except TypeError as erro:
76 | print(erro)
77 | except Exception as erro:
78 | print("Ocorreu um erro diferente dos que já foram tratados ao tentar mover arquivo(s)")
79 |
80 | def move_files_duplicates(source_folder:str='',identify_duplicate:str='', identify_duplicate_final:str='', destination_folder:str=''):
81 |
82 | """
83 | Pasta onde se encontram os arquivos: source_folder='' \n
84 | Pasta Downloads: p.downloads_folder \n
85 | Pasta Temp: p.temp_folder \n
86 | Pasta Temp/Duplicados: p.temp_duplicados \n
87 | Ou a pasta de retorno: return_folder(concessionaria) \n
88 | Pesquisar pelo início do arquivo: identify_duplicate='' \n
89 | p.identify_file(concessionaria, 'begin', duplicate=True) \n
90 | Pesquisar pelo final do arquivo: identify_duplicate_final='' \n
91 | p.identify_file(concessionaria, 'end', duplicate=True) \n
92 | Pasta de destino: destination_folder=''
93 | """
94 |
95 | list_files = os.listdir(source_folder)
96 |
97 | for file in list_files:
98 | if identify_duplicate in file:
99 | if identify_duplicate_final in file:
100 | try:
101 | if os.path.exists(f"{destination_folder}/{file}"):
102 | os.remove(f"{destination_folder}/{file}")
103 | os.rename(f"{source_folder}/{file}", f"{destination_folder}/{file}")
104 | except FileNotFoundError as erro:
105 | print(erro)
106 | except FileExistsError as erro:
107 | print(erro)
108 |
109 | if __name__ == '__main__':
110 |
111 | concessionaria = ''
112 |
113 | move_files(
114 | p.downloads_folder,
115 | p.identify_file(concessionaria, 'begin'),
116 | p.identify_file(concessionaria, 'end'),
117 | p.temp_folder,
118 | 9
119 | )
120 |
121 | move_files_duplicates(
122 | p.downloads_folder,
123 | p.identify_file(concessionaria, 'begin', duplicate=True),
124 | p.identify_file(concessionaria, 'end', duplicate=True),
125 | p.temp_duplicados
126 | )
127 |
128 | move_files(
129 | p.temp_folder,
130 | p.identify_file(concessionaria, 'begin', unzip=True),
131 | p.identify_file(concessionaria, 'end', unzip=True),
132 | p.return_folder(concessionaria)
133 | )
--------------------------------------------------------------------------------
/parameters.py:
--------------------------------------------------------------------------------
1 | # Instalação
2 |
3 | # pip install selenium
4 | # pip install requests
5 | # pip install bs4
6 | # pip install pathlib
7 | # pip install sleep
8 |
9 | import os.path
10 | import security as pw # Interessante toda senha que necessitar utilizar adicionar em um arquivo protegido
11 |
12 | folder_70 = fr''
13 | folder_siparq = fr''
14 | link = ''
15 | page_files = ''
16 | executable_path = r'C:\WebScraping-Selenium-Python\selenium_webdriver\chromedriver.exe'
17 |
18 |
19 | # Obter o caminho das pastas
20 | downloads_folder = os.path.expanduser(r"~\Downloads")
21 | temp_folder = os.path.expanduser(r"~\Documents/EDP/Temp")
22 | temp_duplicados = os.path.expanduser(r"~\Documents/EDP/Temp/Duplicados")
23 |
24 |
25 | def return_folder(concessionaria:'str'=''):
26 | """
27 | Informar o nome da concessionária: concessionaria='Nome'
28 | """
29 | if concessionaria == 'Bandeirante':
30 | path = os.path.expanduser(r"C:\Bandeirante\Retorno")
31 | return path
32 | if concessionaria == 'ESCELSA':
33 | path = os.path.expanduser(r"C:\ESCELSA\Retorno")
34 | return path
35 |
36 | def identify_file(concessionaria:'str'='', position:'str'='', unzip=False, duplicate=False):
37 | """
38 | Informar o nome da concessionária: concessionaria='Nome' \n
39 | Pesquisar pelo início do arquivo: position='begin' \n
40 | Pesquisar pelo final do arquivo: position='end' \n
41 | Se o arquivo estiver descompactado informe: unzip=True \n
42 | Se a busca é por arquivos duplicados informe: duplicate=True
43 | """
44 |
45 | # Utilizado para identificar arquivos que pertencem a cada fornecedor
46 | if concessionaria == 'Bandeirante':
47 | if position == 'begin':
48 | if unzip == True:
49 | file_begin_unzip_band = "CARTAO_"
50 | return file_begin_unzip_band
51 | if duplicate == True:
52 | identify_duplicate = "CARTAO_TODOS_"
53 | return identify_duplicate
54 | else:
55 | file_begin_band = "CARTAO_"
56 | return file_begin_band
57 | elif position == 'end':
58 | if unzip == True:
59 | file_end_unzip_band = "_CONV.TXT"
60 | return file_end_unzip_band
61 | if duplicate == True:
62 | identify_duplicate_final = ").ZIP"
63 | return identify_duplicate_final
64 | else:
65 | file_end_band = "_CONV.ZIP"
66 | return file_end_band
67 | if concessionaria == 'ESCELSA':
68 | if position == 'begin':
69 | if unzip == True:
70 | file_begin_escelsa = "498_COBR_"
71 | return file_begin_escelsa
72 | if duplicate == True:
73 | identify_duplicate = "498_COBR_"
74 | return identify_duplicate
75 | else:
76 | file_begin_escelsa = "498_COBR_"
77 | return file_begin_escelsa
78 | elif position == 'end':
79 | if unzip == True:
80 | file_end_unzip_escelsa = "_CONV.TXT"
81 | return file_end_unzip_escelsa
82 | if duplicate == True:
83 | identify_duplicate_final = ").ZIP"
84 | return identify_duplicate_final
85 | else:
86 | file_end_escelsa = "_CONV.ZIP"
87 | return file_end_escelsa
88 |
89 | if __name__ == '__main__':
90 |
91 | print(identify_file('Bandeirante', 'begin'))
92 | print(identify_file('Bandeirante', 'end', unzip=True))
93 | print(identify_file('Bandeirante', 'begin', duplicate=True))
94 |
95 | print(return_folder('Bandeirante'))
96 |
--------------------------------------------------------------------------------
/security.py:
--------------------------------------------------------------------------------
1 | # FTP
2 | ftp70_host = ""
3 | ftp70_username = ""
4 | ftp70_password = ""
5 | ftp70_porta = 0
6 |
7 | # Servidor
8 | siparq = ""
9 |
10 | # Conexão com o Banco
11 | driver = "{SQL Server Native Client 11.0}"
12 | name_db = ""
13 | user_db = ""
14 | password_db = ""
15 |
16 | # E-mail
17 | email_cobranca = ""
18 | email_teste = ""
19 |
20 | def user(concessionaria, tipo):
21 | if concessionaria == 'Bandeirante':
22 | if tipo == 'User':
23 | username_field = ''
24 | return str(username_field)
25 | if tipo == 'Password':
26 | password_field = ''
27 | return str(password_field)
28 | if concessionaria == 'ESCELSA':
29 | if tipo == 'User':
30 | username_field = ''
31 | return str(username_field)
32 | if tipo == 'Password':
33 | password_field = ''
34 | return str(password_field)
--------------------------------------------------------------------------------
/selenium_webdriver/Leia-me.txt:
--------------------------------------------------------------------------------
1 | Descompactar o arquivo "chromedriver_win32.zip"
2 | E copiar o seu conteúdo para dentro da pasta raiz do Python
3 |
4 | 1ª) Clicar com botão direito em "Este Computador / Meu Computador"
5 | 2ª) Clicar em Configurações avançadas do sistema
6 | 3ª) Clicar em "Variáveis de Ambiente"
7 | 4ª) Selecionar "Path" e clicar em Editar
8 | 5ª) Clicar em Novo
9 | 6ª) Adicionar o caminho onde colocou o "chromedriver.exe"
10 |
11 | Ou acesse o site para baixá-lo.
12 | https://chromedriver.chromium.org/downloads
13 | https://stackoverflow.com/questions/29858752/error-message-chromedriver-executable-needs-to-be-available-in-the-path
--------------------------------------------------------------------------------
/selenium_webdriver/chromedriver.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marquescharlon/Automatizacao-Selenium-Python/4ded05350eaf8bb11ac953125dcd3493cbc310a3/selenium_webdriver/chromedriver.exe
--------------------------------------------------------------------------------
/selenium_webdriver/chromedriver_win32.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marquescharlon/Automatizacao-Selenium-Python/4ded05350eaf8bb11ac953125dcd3493cbc310a3/selenium_webdriver/chromedriver_win32.zip
--------------------------------------------------------------------------------
/unzip_files.py:
--------------------------------------------------------------------------------
1 | import os.path
2 | import os
3 | import zipfile as zf
4 |
5 | def files(source_folder:str='', file_begin:str='', file_end:str='', delete_file=False):
6 |
7 | """
8 | Pasta onde se encontram os arquivos: source_folder='' \n
9 | Pesquisar pelo início do arquivo: file_begin='' \n
10 | p.identify_file(concessionaria, 'begin') \n
11 | Pesquisar pelo final do arquivo: file_end='' \n
12 | p.identify_file(concessionaria, 'end') \n
13 | Deseja excluir o arquivo .ZIP? delete_file=True
14 | """
15 |
16 | files = os.listdir(source_folder)
17 |
18 | for file in files:
19 | if file_begin in file:
20 | if file_end in file:
21 |
22 | path = os.path.join(rf'{source_folder}', file)
23 |
24 | with zf.ZipFile(rf"{path}") as z:
25 | z.extractall(rf'{source_folder}')
26 |
27 | if delete_file == True:
28 | os.remove(rf"{path}")
29 |
30 | if __name__ == '__main__':
31 |
32 | import parameters as p
33 |
34 | concessionaria = ''
35 |
36 | files(
37 | p.temp_folder,
38 | p.identify_file(concessionaria, 'begin'),
39 | p.identify_file(concessionaria, 'end'),
40 | delete_file=False
41 | )
--------------------------------------------------------------------------------