¿Como podria leer un fichero.txt linea a linea y pasar esos valores a a un archivo Python?

publicado por: Anonymous
with open("login.txt") as fichero:
    dirServer = fichero.readline().split(":")[1].strip()
    usuario = fichero.readline().split(":")[1].strip()
    passwd = fichero.readline().split(":")[1].strip()

datos = {}
busco = ['dirServer', 'usuario', 'passwd']

with open("login.txt") as fichero:
    for linea in fichero:
        trozos = linea.split(":")
        if trozos[0] in busco:
            datos[trozos[0]] = trozos[1].strip()

# Importa la clase FTP, necesaria para establecer una conexión, enviar y recibir datos.
from ftplib import FTP

# Se crea una instancia de dicha clase. Toma como argumentos host, user, passwd
ftp = FTP('dirServer')

# Hacemos el login de usuario y passwd, 
ftp.login(user='usuario', passwd='passwd')

# La función FTP.cwd() es utilizada para cambiar de directorio o carpeta
ftp.cwd("zzz") 

# Retorna información sobre los archivos y carpetas en la ubicación actual.
ftp.retrlines('LIST')

# Ejecuta el comando RETR para descargar el archivo README en modo binario.
# El segundo parámetro es una función callback que será llamada por cada bloque de bytes recibidos,
# que a su vez estos son pasados como argumento a dicha función. En este caso se pasa la función write de un objeto file
ftp.retrbinary('RETR prueba.txt', open('PruebaFtp.txt', 'wb').write)

ftp.quit()

¿Como podria pasarle el valor de ip, user, passwd desde un fichero.txt?

fichero.txt
dirServer: 10.0.0.4
usuario: Administrador
passwd: **********

me da esta serie de errores

Traceback (most recent call last):
  File "C:Usersbecario2admMy DocumentsLiClipse 
Workspaceprueba2prueba2.py", line 28, in <module>
ftp = FTP('dirServer')
  File "C:Usersbecario2admAppDataLocalProgramsPythonPython37-32libftplib.py", line 117, in __init__
self.connect(host)
  File "C:Usersbecario2admAppDataLocalProgramsPythonPython37-32libftplib.py", line 152, in connect
source_address=self.source_address)
  File "C:Usersbecario2admAppDataLocalProgramsPythonPython37-32libsocket.py", line 707, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
  File "C:Usersbecario2admAppDataLocalProgramsPythonPython37-32libsocket.py", line 748, in getaddrinfo
  for res in _socket.getaddrinfo(host, port, family, type, proto, flags):

socket.gaierror: [Errno 11001] getaddrinfo failed

solución

Si el fichero tiene únicamente lo que muestras en la pregunta (no sé por qué había entendido yo inicialmente que había varios usuarios y contraseñas en el fichero), la cosa se reduce a leer las líneas y separar por donde se hallan los dos puntos.

Asumiendo que además la IP del servidor, el nombre de usuario y la contraseña aparecen exactamente en ese orden en el fichero, la cosa es trivial:

with open("fichero.txt") as fichero:
  servidor = fichero.readline().split(":")[1].strip()
  usuario = fichero.readline().split(":")[1].strip()
  clave = fichero.readline().split(":")[1].strip()

ftp = FTP(servidor) 
ftp.login(user=usuario, passwd=clave)
ftp.cwd("zzz") 
ftp.retrlines('LIST')
ftp.retrbinary('RETR prueba.txt', open('PruebaFtp.txt', 'wb').write)
ftp.quit()

Es decir, una vez abierto el fichero, cada vez que uses readline() te devuelve una línea del mismo, sobre la cual hacemos .split(":") para separarlo en dos partes. Esta función devuelve una lista con las partes encontradas, y de ellas nos quedamos con la segunda (elemento [1] de la lista). Sobre ese valor, que será ya una cadena, hacemos strip() para eliminar los espacios que dicha cadena pueda tener por delante o por detrás, y el carácter de nueva línea que aparecerá al final de la misma.

Como esta solución es bastante frágil (un cambio en el orden de las líneas del fichero, o la existencia de líneas en blanco al principio o entre los elementos, haría que el programa dejara de funcionar), proporciono otro enfoque.

Se trata ahora de tener una lista con los posibles nombres de los datos en que estamos interesados en el fichero, para comparar cada línea leida con esos nombres y entonces extraer el apropiado, guardando los valores en un diccionario. Después usamos ese diccionario en la conexión FTP:

datos = {}
busco = ['dirServer', 'usuario', 'passwd']

with open("fichero.txt") as fichero:
  for linea in fichero:
    trozos = linea.split(":")
    if trozos[0] in busco:
      datos[trozos[0]] = trozos[1].strip()

# Verificar que hemos encontrado toda la información que queríamo
# El diccionario debe tener tantas claves como las que buscaba
if len(datos) != len(busco):
  print("El fichero no tiene el formato esperado")
else:
  ftp = FTP(datos["dirServer"])
  ftp.login(user=datos["usuario"], passwd=datos["passwd"])
  ftp.cwd("zzz") 
  ftp.retrlines('LIST')
  ftp.retrbinary('RETR prueba.txt', open('PruebaFtp.txt', 'wb').write)
  ftp.quit()

Otra posibilidad

Si puedes elegir el formato del fichero con los datos, lo más correcto (y sencillo, y flexible) sería usar un formato estándar que tenga buen soporte en python. Podrías usar JSON, pero la tendencia actual es ir a otros lenguajes más fáciles de leer/escribir por humanos, como YAML o TOML.

En concreto, TOML, aunque menos conocido que otros, está ganando fuerza al ser preferido por muchos (por ser muy sencillo de parsear). Tu información guardada en un fichero TOML tendría este aspecto:

dirServer = '192.68.1.1'
usuario = 'abulafia'
passwd = 'secreto 😜'

Y para leerlo te bastaría hacer:

import toml
datos = toml.decoder.load("fichero.toml")

y ya tendrías los datos en un diccionario. A partir de aquí seguirías como en la respuesta anterior, es decir, en datos["username"] tienes el nombre de usuario, etc.

Por desgracia toml no viene en la librería estándar python1, y tendrás que instalarlo con pip, pero es un módulo muy pequeño, puro python y sin dependencias.

1 Aunque quizás venga en el futuro porque toml ha sido elegido por la comunidad python como el lenguaje en el cual especificar los parámetros necesarios para la creación y distribución de módulos de terceros.

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *