Mostrando entradas con la etiqueta Textos. Mostrar todas las entradas
Mostrando entradas con la etiqueta Textos. Mostrar todas las entradas

martes, 18 de noviembre de 2025

Textos. Python

Aplicación práctica

Extracción de texto a partir de imágenes




Presento en esta entrada la primera aplicación práctica de los procedimientos tratados en esta subsección relativa al trabajo con textos mediante Python. Primero nos situaremos en contexto, después mostraré el script y finalmente lo explicaré.

Me planteo crear una aplicación que facilite la evaluación del grado de adquisición del sistema fonológico. Para ello selecciono la prueba PLON-R Fonología y necesito estudiar su fundamentación teórica, por lo que accedo a su manual. Dado que se ese manual es un documento en papel, caben dos opciones: copiar manualmente la información que considere necesaria o capturarla en imágenes (vg. en png).

Dado que la primera opción lleva cierto tiempo, opto por la segunda, pero para acceder al contenido necesito convertir esas imágenes en texto. Para ello creo un directorio (Textos) donde copio las imágenes ordenadas según la lógica de su contenido y creo un script Python para acceder al texto que contienen las imágenes.

import os
import pytesseract
from PIL import Image

#Ruta a Tesseract
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

'''
Acceder al listado de documentos png del directorio Textos
'''
lista_img = []
#Listado imágenes . Acceso al directorio
directorio = 'Textos/'
os.chdir(directorio)
lista_archivos = os.listdir('.')

for elemento in lista_archivos:
    lista_img.append(elemento)

'''
Acceder a las imágenes para extraer el texto y copiarlo en documento txt
'''
for elemento in lista_img:
    img = Image.open(elemento)
    # Extraer texto
    texto = pytesseract.image_to_string(img, lang ='spa')
    #Escribir el texto en el archivo .txt
    archivo = open('plon_fono.txt','a', encoding='utf-8')
    archivo.write(texto+'\n')
    archivo.close()

Explico a continuación este script que, como puedes ver, requiere trabajar con tres bibliotecas Python:
  • os (import os) para generar el listado del contenido del directorio Textos y automatizar el acceso a esos documentos (imágenes png)
  • Pillow (from PIL import Image) para acceder a cada una de las imágenes
  • Pytesseract (import pytesseract) para trabajar con el programa OCR Tesseract.
En primer lugar establecemos la ruta para acceder al programa OCR (pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'), paso necesario para el procesamiento OCR de las imágenes.

En segundo lugar accedemos al directorio Textos mediante las funciones os y listamos los archivos que contiene como textos para su posterior uso en el bucle de acceso a las imágenes.

Para ello identificamos el directorio (directorio = 'Textos/') y nos ubicamos en él (os.chdir(directorio)) para extraer su contenido (lista_archivos = os.listdir('.')) y pasarlo a una lista (lista_img = []) de string mediante la función append() (lista_img.append(elemento)) dentro de un bucle que recorre el contenido del directorio (for elemento in lista_archivos:). Sobre esa lista de nombres de archivos desarrollaremos la segunda parte del script.

Dicha segunda parte consiste en recorrer los archivos, acceder a su contenido y convertirlo en texto mediante procedimiento OCR. Todo ello se desarrolla dentro de un segundo bucle for (for elemento in lista_img:) que accede secuencialmente a cada imagen usando la librería Pillow (img = Image.open(elemento)) que pasa la imagen la función image_to_string() de la biblioteca pytesseract (que conecta con el programa OCR Tesseract (texto = pytesseract.image_to_string(img, lang ='spa')) que convierte el contenido de la imagen en un texto editable.

Simultáneamente, en el mismo bucle, se desarrolla la tercera fase que consiste en aplicar las funciones de creación, escritura y cierre de documentos externos txt con que cuenta Python.

Esta parte del script repite cíclicamente el proceso de crear/acceder al documento txt (archivo = open('plon_fono.txt','a', encoding='utf-8')) y escribir el contenido obtenido mediante el procedimiento identificado como segunda parte del script...

(texto = pytesseract.image_to_string(img, lang ='spa')) -> (archivo.write(texto+'\n'))

... y finaliza, ya fuera del bucle, con el cierre del documento (archivo.close()).

El resultado de la aplicación de este script es un documento txt, un tanto "desmadejado" para perfectamente útil para incorporar el contenido de esos documentos obtenidos inicialmente como imágenes a nuestro análisis del documento.

Documentos. A efectos de facilitarte el acceso al resultado y la réplica de esta práctica de dejo a continuación algunos materiales que deberás descargar desde este enlace: textos_imagenes y descomprimirlo. Contiene la carpeta Textos, que a su vez contiene unas imágenes y el documento txt resultante (plon_fono.txt), y el script textos_plon.py.


miércoles, 22 de octubre de 2025

Textos. Python.

Textos en imágenes

Obtención del texto (II)



Aunque en la entrada anterior usamos Pillow como programa de procesamiento de imágenes (con una función muy simple, por cierto: cargar la imagen), lo cierto es que lo normal es que se haga uso de OpenCV por su mayor potencia y funcionalidad, así que tendremos que incorporarlo a nuestro arsenal de recursos de automatización del acceso a textos.


Pero lo que quedó patente en la [entrada anterior] es que para lo que lo utilizamos en ese script (plenamente exitoso, por cierto), Pillow es más que suficiente, así que cuando la imagen no presente mayores dificultades y su tratamiento sea tan simple como el realizado, podemos trabajar perfectamente con esa biblioteca con total confianza. 

Otra cosa es que el tratamiento a hacer de la imagen de referencia exija actuaciones de mayor complejidad. En ese caso es posible que OpenCV ofrezca mayor rendimiento, aunque sinceramente tengo mis dudas...

En todo caso lo mejor es que también practiquemos a extraer texto de imágenes usando OpenCV. Y a ello vamos tomando como referencia esta imagen, que en principio se presenta con mayor complejidad gráfica y también con mayor utilidad (obtener el texto de páginas escaneadas de cuentos o de libros de texto o de presentaciones ppt previamente convertidas en capturas de pantalla, por ejemplo)


Este es ahora el script:

import cv2
import pytesseract

#Asociar pytesseract a Tesseract
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

# Cargar imagen
img = cv2.imread("img/img3.png")

# Convertir la imagen a escala de grises
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Aplicar threshold para convertir la imagen a binario
threshold_img = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

# Pasar la imagen al progama OCR pytesseract
text = pytesseract.image_to_string(threshold_img, lang='spa')

# Imprimir el texto extraído
print(text)

Puedes apreciar que sustituimos Pillow por OpenCV (import cv2), biblioteca que usamos para cargar la imagen (img = cv2.imread("img/img3.png")), pero también para tratarla a fin de facilitar el escaneo final...
  • Primero la convertimos a escala de grises (gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY))
  • Y después la convertimos a binario (threshold_img = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1])
... aunque puedes comprobar que ninguna de las dos instrucciones es estrictamente necesaria y que su uso no cambia sustancialmente el resultado (que realmente es mejorable), pero lo que aquí es poco relevante, en otros contextos puede ser la diferencia entre un buen acceso al texto o un fracaso, así que bueno es saberlo, aunque ahora parezca que nos sobra.

El resto del script (no hay mucho más, pero es importante) es igual que en el script en el que usamos Pillow:
  • La conexión entre Tesseract y pytesseractpytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
  • El escaneo de la imagen (text = pytesseract.image_to_string(threshold_img, lang='spa'))
  • Y la visualización del texto en pantalla (print(text))
También en este caso obviamos el tratamiento del texto y su posible archivo como documento. Ambas tareas quedan pendientes para aplicaciones prácticas reales.

Textos. Python

Textos en imágenes

Obtención del texto (I)



Te supongo ya dispuesto a obtener texto de una imagen, esto es, con el software correctamente instalado. Partiendo de aquí vamos a practicar la extracción de texto de imágenes partiendo de material sencillo. Ya llegará el momento de aplicarnos a fondo en contextos reales de intervención.


Para empezar, un documento sencillo y poca pretensión de nivel de logro: nos conformaremos con obtener el texto que contiene la imagen y visualizarlo en el el Shell o en el cmd. Esta es la imagen...


... y este el script que explico a continuación:

import pytesseract
from PIL import Image

#Es necesario incluir la ruta a Tesseract para trabajar con pytesseract

pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

# Cargar la imagen con Pillow
img = Image.open('img/img_txt.jpg')

# Extraer texto
texto = pytesseract.image_to_string(img, lang ='spa')

#Escribir el texto en pantalla
print(texto)

Como ves es un script muy simple en el que, además del módulo pytesseract también importamos la librería Pillow, concretamente su módulo básico (from PIL import Image), ya que la necesitamos para cargar la imagen (img = Image.open('img/img_txt.jpg')).

Pero fíjate (y es muy importante) que previamente deberemos incluir una instrucción que comunique pytesseract con Tesseract (existen otras opciones, pero esta es la más sencilla). De no hacerlo no funcionará el script y no obtendremos el texto.

pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
 
Te recomiendo que identifiques la ubicación de Tesseract en tu ordenador (será una dirección igual o muy similar a la mía) y copies esta instrucción al inicio de tus script.

La instrucción que sigue es la clave del procedimiento (texto = pytesseract.image_to_string(img, lang ='spa')), ya que emplea la función pytesseract image_to_string() que requiere dos parámetros, la imagen sobre la que trabajar y el idioma a aplicar (recuerda que en la instalación de Tesseract seleccionaste una serie de idiomas para aplicar OCR), que en nuestro caso es el español (lang ='spa').

Ahora sólo resta visualizar el texto obtenido por pantalla (print(texto)), aunque en una situación real posiblemente lo tendríamos que manipular para mejorar su legibilidad y posteriormente archivar en un documento txt (por ejemplo).




Textos. Python.

Textos en imágenes

Recursos OCR


Cuando hemos aprendido (más o menos) a obtener el texto que contiene un documento PDF, se nos presenta un nuevo desafío: obtener el texto presente en una imagen.


Tendremos ocasión de conocer diversas casuísticas en las que esto se da, pero por ahora nos quedaremos con lo siguiente: unos padres te presentan un informe de un servicio externo en formato papel (hecho muy común) y tú lo escaneas para disponer del documento en formato digital (de paso devuelves el papel a sus dueños) y cuando vas a acceder a su contenido con tus recientes habilidades de manejo de PDF mediante PyPDF2 resulta que el contenido es inaccesible porque, vete a saber por qué, lo que el documento PDF contiene es, en realidad, una imagen.  Se te presentan tres opciones (después de que se te pase el consiguiente cabreo): volver a solicitar el documento a los padres y comprobar que escaneas correctamente el documento como texto (si es que su calidad lo permite), imprimes el documento escaneado y vuelves a intentar un escaneo correcto (si es posible...) o aprendes a obtener el texto que contiene ese PDF que milagrosamente resulta ser una imagen.

A lo mejor la tercera opción resulta ser la más complicada, pero te aseguro que es la mejor, al menos en el medio plazo.

Esta un tanto rocambolesca situación no lo es tanto en la vida real en la que obtener texto de imágenes es una funcionalidad de mucho más uso del que pensamos. En nuestro caso como SEO tendremos muchas ocasiones para comprobarlo; algunas de ellas, como dije, las trataremos en este blog.

La solución Python tiene poco de milagrosa, ya que se basa precisamente en aplicar lo que deseamos desde un principio cuando escaneamos el documento: obtener un texto mediante tecnología OCR. Esta es la base del procedimiento: incorporar un software OCR y manejarlo desde Python.

El OCR es el programa Tesseract, que puedes descargar desde [este enlace] y la biblioteca Python que necesitas para trabajar con él es pytesseract, cuya web oficial tienes en [este enlace]. Te recomiendo que te tomes las cosas con calma y que consultes ambas webs antes de proceder a la instalación del software; esto es especialmente necesario para el OCR, ya que su instalación requiere cierto cuidado y debe ser previa a la de la biblioteca Python.

martes, 30 de septiembre de 2025

Textos. Python.


Acceso a archivos





Para completar el tema del manejo de archivos txt mediante Python, nos queda hablar de la lectura o acceso al contenido, cuestión ésta de gran interés para la creación de script potentes en cuando a su funcionalidad.


Hasta el momento hemos visto la [creación y apertura de un archivo] y [cómo escribir en él], pero desconocemos cómo podemos acceder a su contenido, siendo como es fundamental para el desarrollo de un script de cierta complejidad.

Explico a continuación las fases por las que pasa la lectura de un archivo, entendiendo lectura como sinónimo de acceso al contenido:
  • Primero: acceso al archivo, paso previo, común también al proceso de escritura.
  • Segundo: lectura del contenido. Dentro de esta segunda fase deberemos distinguir dos condiciones alternativas: si deseamos acceder al texto como un bloque o si nos interesa hacerlo línea por línea. Esta opción está determinada, fundamentalmente, por el modo en que se ha escrito el contenido en el archivo.
Veamos ahora cómo concretamos en código cada fase y cada opción, ya que todas ellas permiten diferente formulaciones, empezando por el acceso (y apertura) del archivo, acción que permite dos formulaciones: la básica…

Archivo = ‘texto.txt’ 
contenido = open(archivo,’r’, encoding=‘utf-8’)

Cuerpo de instrucciones

contenido.close()

… en donde cambiamos el segundo parámetro por ‘r’ (reader) para especificar la acción que vamos a aplicar sobre el archivo, y la simplificada, que nos ahora la función de cierre

with open(archivo,’r’, encoding=‘utf-8’) as contenido:  

La segunda parte del proceso se basa en la lectura del contenido que se realiza, en principio con la función o método read()

texto_leer = contenido.read()

… que almacena en texto_leer toda la información contenida en el archivo referenciado como  contenido.

Pero si el contenido el archivo fuera una lista de palabras (por ejemplo) que ocupara varias líneas (por ejemplo, los días de la semana), podríamos usar el mismo procedimiento, pero obtendríamos un texto único, no una lista de los días de las semana (1). Si necesitamos acceder a la lista podemos optar por crearla (lista= []) y usar un bucle for para recorrer el archivo abierto añadiendo (lista.append()) cada elemento a la lista, o puedes optar por usar la función readlines() y ahorrarte el bucle (2).

En este segundo caso depende, como ya dije, de cómo está “escrito” el contenido en el archivo. Empecemos por la forma más simple, suponiendo que el contenido del archivo es un texto formado por uno o varios párrafos y que nuestro interés es usar ese contenido para informar al usuario del script sobre el funcionamiento del mismo. En este supuesto, necesitamos leer el contenido y pasarlo a una variable-cadena que después mostraremos en pantalla. Para ello, sobre texto_lista.txt (listado de días de la semana)…

archivo = ‘texto_lista.txt’
lineas = []
docum = open(archivo,’r’, encoding=‘utf-8’)
lineas = docum.realdlines()
lin = len(lineas)
print(f’Número de elementos de la lista {lin}\n’)
for i in range(lin):
    print(lineas[i].rstrip())
docum.close()

Este script devuelve una lista de elementos formada por el contenido de cada una de las líneas del documento. La función len() nos permite ver que esa lista consta de 7 elementos y sirve de referencia para limitar el número de ciclos que recorre for (for i in range(lín)) (3).

Si quieres confirmar que lineas es una lista y no una cadena de caracteres, sólo tienes que solicitar que se imprima un elemento mediante…

print(lineas[0]) -> Te devuelve lunes (4)

… pero lo realmente interesante es el conjunto de posibilidades que te ofrece el uso de lineas como lista.

NOTAS

(1) La diferencia puede que no la apreciemos si pedimos imprimir la variable usada como referencia (vg. texto_leer), pero sí si queremos acceder a un elemento concreto de la lista. Por ejemplo print(texto_leer[0]) no nos devuelve Lunes, nos devuelve l (primer elemento (0) de la cadena)
(2) También disponemos de la función readline(), que lee y devuelve caracteres en forma de cadena hasta encontrar un salto de línea (\n).
(3) Recuerda que rstrip() sirve para eliminar los saltos de línea
(4) Si lineas fuera una cadena devolvería l

sábado, 27 de septiembre de 2025

Textos. Python


E
scritura en archivos



Siguiendo con la lógica de la [entrada anterior], una vez creado (y abierto) el archivo deberemos proceder trasladar a él los datos generados por nuestro script, procedimiento llamado escritura (1). Dedicaremos esta entrada a explicar las diferentes formas que tenemos de escribir en un archivo txt desde un script de Python. 



Como sabemos, de las instrucciones que usamos como concreción del segundo parámetro de la función open(), tres nos permiten escribir (2) en el archivo: xw a

Cada una de ellas tiene un comportamiento particular, tanto respecto a la existencia previo (o no) del archivo, como al modo de trabajar con él.

  • La opción x (create) parece, en principio, ser la más apropiada, pero tiene un inconveniente: si el archivo que pretendemos crear ya existe, devuelve error, por lo que es necesario asegurar que dicho archivo no exista (3).
  • La opción w crea el archivo si éste no existe y no devuelve error, pero borrar lo que contenga y sitúa el cursor al inicio del archivo.
  • Por último, la opción a funciona igual que la anterior y tiene la ventaja de no alterar el contenido previo del archivo en caso de que éste exista, situando el cursor al final del archivo.
Sabiendo lo anterior podemos optar por la opción que mejor se ajuste a nuestras necesidades (4). Por ejemplo:
  • Si la prioridad es crear un nuevo archivo conociendo a ciencia cierta que no existe, cualquiera de las tres opciones es válida. x parece la más específica, pero en realidad las tres tienen, en este caso, el mismo comportamiento, ya que la posición del cursor dentro del archivo (posición de partida para escribir en él) siempre será el inicio del mismo (5).
  • Si lo que deseamos es continuar escribiendo en un archivo ya creado, la mejor opción es a, ya que nos garantiza que se respeta el contenido previo y que el nuevo se escribe a continuación.
  • Si nuestro cometido es mantener actualizado y sin redundancias un determinado archivo, la mejor opción es w, ya que nos garantiza que no se producirá error (como en el caso de x) si el archivo ya existe, y que siempre estará actualizado.
Vamos a explicar a continuación el proceso mismo de escritura, empezando por la la función write() en su uso más simple. Un ejemplo...

archivo = open('texto1.txt','x', encoding='utf-8')
archivo.write('Pedro como plátanos')
archivo.close()

... una variación sobre el mismo tema, sustituyendo la cadena por la variable que la referencia...

frase ='Pedro come plátanos'

archivo = open('texto1.txt','x', encoding='utf-8')
archivo.write(frase)
archivo.close()

... y una tercera formulación, más sofisticada e interactiva, pero en lo principal, la misma:

nombre = input('Dime el nombre de la persona: ')
verbo = input(f'¿Qué hace {nombre }? ')
objeto = input(f'¿Qué {verbo} {nombre} ')

frase = (f'{nombre} {verbo} {objeto}') #Concetana el contenido de las tres variables

archivo = open('texto1.txt','x', encoding='utf-8')
archivo.write(frase)
archivo.close()

También podemos trabajar con colecciones de datos y con bucles, previamente a la escritura del contenido en el archivo y en proceso de escritura.

Pensemos, por ejemplo, en una lista de vocabulario básico que almacenamos inicialmente en una lista y que después escribimos en un archivo.

rutas=['Pera',
        'Plátano',
        'Manzana',
        'Naranja',
        'Fresa'
        ]

archivo = open('texto1.txt','x', encoding='utf-8')

for fruta in frutas:
    archivo.write(fruta)

archivo.close()

Aunque este script nos permite crear, acceder y escribir en el archivo (texto1.txt), el problema que nos encontramos (al acceder al acceder al archivo) es el siguiente: PeraPlátanoManzanaNaranjaFresa. Todas las palabras se escribieron juntas, en una misma línea. Es posible que queramos que se escriban en una única línea, una detrás de otra (a modo de lista), pero lo que es seguro es que no nos interesa que aparezcan en un sólo bloque, como una única palabras. Incluso es posible que deseemos que cada una de ellas se escriba en una línea diferentes. Vamos a ver cómo lo podemos solucionar. 
  • Por ejemplo, si usamos la siguiente instrucción (archivo.write(' ')) tras (archivo.write(fruta)) obtendremos Pera Plátano Manzana Naranja Fresa. La razón: tras cada elemento de la lista escribimos un espacio mediante esa nueva instrucción.
  • Siguiendo este procedimiento, y manteniendo la escritura del listado en una misma línea, podemos añadir cualquier carácter o grupo de caracteres para separar cada elemento de la lista, como, por ejemplo sustituyendo (archivo.write(' ')) por (archivo.write('||')), con lo que obtendremos Pera||Plátano||Manzana||Naranja||Fresa||.
  • Y estarás pensando que si usas el carácter salto de línea es posible escribir la lista en diferentes líneas (archivo.write('\n')). Y estarás en lo cierto.
Pues bien, el mismo efecto que obtenemos con el uso del bucle (for fruta in frutas:) lo obtenemos usando la función join() como te muestro en el siguiente script (6)

frutas=['Pera',
        'Plátano',
        'Manzana',
        'Naranja',
        'Fresa'
        ]

archivo = open('texto1.txt','x', encoding='utf-8')

texto = '\n'.join(frutas) #Si no queremos saltos de línea podemos usar, por ejemplo '||'

archivo.write(texto)

archivo.close()

... con el que conseguimos el mismo efecto que con la anterior formulación del script con bucle (7).

Cuando el texto a guardar es de varias líneas, podemos usar el método writelines() en sustitución de writer(). También este método nos ahorra el uso del bucle, ya que escribe las múltiples líneas de las que puede estar compuesto un texto o los diferentes elementos de una lista...

frutas=['Pera',
        'Plátano',
        'Manzana',
        'Naranja',
        'Fresa'
        ]

archivo = open('texto1.txt','x', encoding='utf-8')

archivo.writelines(frutas)

archivo.close()

... pero tiene un problema: o modificamos la lista introduciendo "separadores" entre su elementos, o lo que se escribe es una única "palabra" (PeraPlátanoManzanaNaranjaFresa) (8)

Y ya puestos a ahorrar, si queremos prescindir de la función close() (archivo.close()) podemos recurrir with (9), como, por ejemplo...

frutas = ["Manzana\n", "Pera\n", "Plátano\n"]
with open("texto1.txt", 'w', encoding='utf-8') as archivo:
archivo.writelines(frutas)

... cuyas sentencias subordinadas (en este caso archivo.writelines(frutas)) podemos formular de formas similares a como hicimos en los ejemplos anteriores (10)

NOTAS 

(1) Por oposición al de recuperación del contenido del archivo o de lectura.
(2) Crear, si no está creado, y escribir en el archivo. x da error si el archivo ya existe, cosa que no sucede ni con a ni con w. La diferencia entre ambos se explica en el texto de la entrada.
(3) La función isfile() nos puede ayudar, ya que devuelve un valor booleano (True/False) que controla la posible existencia del archivo.
(4) Si mantenemos la lógica de lo que estamos haciendo (escribir sobre un archivo recién creado), cualquiera de las tres opciones nos vale, aunque en sentido estricto deberíamos usar x.
(5) Es posible que esta sea la causa de que en algunos manuales no se haga mención de la opción x, entendiéndola redundante en caso de inexistencia del archivo y potencialmente negativa en caso de duda al respecto. Esta es una observación personal no contrastada, por lo que ha de tomarse con reservas. Dada la importancia que tiene en el proceso de escritura (y lectura) conocer la posición que ocupa el cursor interno, Python dispone de funciones específicas para este fin. Estas opciones no van a ser tratadas en esta entrada, ya que tiene carácter introductorio, pero las explicaré cuando el objetivo de aprendizaje (y uso práctico) lo haga necesario.
(6) Observa que en este nuevo script han cambiado algunas cosas más que el bucle.
(7) Y si sustituimos '\n' por cualquier combinación de caracteres (vg texto = '||'.join(frutas) ) obtendremos resultados similares a las otras formulaciones de script: todos los elementos en la misma línea, separados por esos caracteres (vg, de  nuevo Pera||Plátano||Manzana||Naranja||Fresa||)
(8) Una posible solución es escribiendo la lista como sigue: frutas=['Pera', '\n','Plátano','\n',       'Manzana','\n','Naranja','\n','Fresa']. En estos casos personalmente prefiero usar el bucle o la función join().
(9) Que realmente ahorra más que la instrucción archivo.close(), como se puede comprobar en la entrada.
(10) Aquí buscamos la forma extrema de simplificación del código que permite el uso de with para que se aprecie mejor el efecto indicado en 9. Puede que no sea el que mejor se acomode a tus necesidades.