Warum wird das HTML-Tag „meta-description“ nicht übersetzt?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
me_suzy
User
Beiträge: 8
Registriert: Dienstag 11. Oktober 2022, 08:03

Ich habe diesen Python-Code, der sehr gut funktioniert.
Ich kann also alle HTML-Tags übersetzen, außer einem: `<meta name="description" content="...">`
kann mir jemand mit einer lösung helfen? Ich weiß nicht, warum dieses Tag nicht funktioniert, um es zu übersetzen.


Code: Alles auswählen

from bs4 import BeautifulSoup
from bs4.formatter import HTMLFormatter
from googletrans import Translator
import requests


translator = Translator()


class UnsortedAttributes(HTMLFormatter):
def attributes(self, tag):
     for k, v in tag.attrs.items():
         yield k, v


files_from_folder = r"c:\carte\1"


use_translate_folder = True


destination_language = 'fr'


extension_file = ".html"


import os
directory = os.fsencode(files_from_folder)


def recursively_translate(node):
for x in range(len(node.contents)):
     if isinstance(node.contents[x], str):
         if node.contents[x].strip() != '':
             try:
                 node.contents[x].replaceWith(translator.translate(node.contents[x], dest=destination_language).text)
             except:
                 pass
     elif node.contents[x] != None:
         recursively_translate(node.contents[x])
amount = 1
for file in os.listdir(directory):
filename = os.fsdecode(file)
print(filename)
if filename == 'y_key_e479323ce281e459.html' or filename == 'directory.html':
     continue
if filename.endswith(extension_file):
     with open(os.path.join(files_from_folder, filename), encoding='utf-8') as html:
         soup = BeautifulSoup('<pre>' + html.read() + '</pre>', 'html.parser')
         for title in soup.findAll('title'):
             recursively_translate(title)
         for meta in soup.findAll('meta', {'name':'description'}):
             try:
                 meta['content'] = recursively_translate(meta['content'])
             except:
                 pass

         for p in soup.findAll('p', class_='text_obisnuit2'):
                 recursively_translate(p)

     print(f'{filename} translated ({amount})')
     amount += 1
     soup = soup.encode(formatter=UnsortedAttributes()).decode('utf-8')
     new_filename = f'{filename.split(".")[0]}_{destination_language}.html'
     if use_translate_folder:
         try:
             with open(os.path.join(files_from_folder+r'\translated', new_filename), 'w', encoding='utf-8') as new_html:
                 new_html.write(soup[5:-6])
         except:
             os.mkdir(files_from_folder+r'\translated')
             with open(os.path.join(files_from_folder+r'\translated', new_filename), 'w', encoding='utf-8') as new_html:
                 new_html.write(soup[5:-6])
     else:
         with open(os.path.join(files_from_folder, new_filename), 'w', encoding='utf-8') as html:
             html.write(soup[5:-6])

test.html

Code: Alles auswählen

<html>
<head>

<title>It really helps me do great things for her</title>
    
<meta name="description" content="What I LOVE to do and what I don't love">

<p class="text_obisnuit2"><em>Buckingham has a new book called Love</em></p>

</body>
</html>
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du solltest dringend diese unqualifizierten try/except Konstrukte loswerden. Die verschleiern Programmierfehler. Exceptions nur spezifisch abfangen. Vielleicht klärt sich dann, was das Problem ist.
me_suzy
User
Beiträge: 8
Registriert: Dienstag 11. Oktober 2022, 08:03

__deets__ hat geschrieben: Dienstag 11. Oktober 2022, 09:24 Du solltest dringend diese unqualifizierten try/except Konstrukte loswerden. Die verschleiern Programmierfehler. Exceptions nur spezifisch abfangen. Vielleicht klärt sich dann, was das Problem ist.
hallo. kannst du mir helfen? Können Sie meinen Kabeljau ein wenig aktualisieren?
Benutzeravatar
Kebap
User
Beiträge: 776
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

me_suzy hat geschrieben: Dienstag 11. Oktober 2022, 09:27 hallo. kannst du mir helfen? Können Sie meinen Kabeljau ein wenig aktualisieren?
Klar, gerne, warum auch nicht...
Ersetze alle Zeilen wie diese:

Code: Alles auswählen

             try:
                 meta['content'] = recursively_translate(meta['content'])
             except:
                 pass
Durch die zweite Zeile allein:

Code: Alles auswählen

            meta['content'] = recursively_translate(meta['content'])
Wenn dann eine Fehlermeldung kommt, kann man die sich anschauen... :mrgreen:
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
me_suzy
User
Beiträge: 8
Registriert: Dienstag 11. Oktober 2022, 08:03

me_suzy
User
Beiträge: 8
Registriert: Dienstag 11. Oktober 2022, 08:03

Kebap hat geschrieben: Dienstag 11. Oktober 2022, 09:50
Ich weiß nicht, wie ich den Fehler beheben soll
Sirius3
User
Beiträge: 18278
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Einrückungen sind leider kaputt, so dass wir nicht genau wissen können, was der Code macht.
Man benutzt keine globalen Variablen, weil das den Code unübersichtlich macht, und sich leicht Fehler einschleichen, die man dann nicht nachvollziehen kann.
Import gehören an den Anfang der Datei.
os.fsencode bzw os.fsdecode habe ich noch nie benutzt, weil sich die Filesystem-Funktionen automatisch darum kümmern.
`x` für einen Laufindex ist eine äußerst schlechte Wahl, weil man mit x eine Fließkommazahl für Berechnungen verbindet und keinen Index.
Über einen Index iteriert man sowieso nicht, weil man auch direkt über die Elemente iterieren kann.
Mit None vergleicht man üblicherweise mit `is None` bzw `is not None`.
Wenn `contents` eine replaceWith-Methode hat, dann sind das keine reinen Strings.

Code: Alles auswählen

def recursively_translate(node, translator):
    for contents in node.contents:
        if isinstance(contents, str): # which type is that?
            if contents.strip() != '':
                contents.replaceWith(translator.translate(contents, dest=destination_language).text)
        elif contents is not None:
            recursively_translate(contents, translator)

Ansonsten scheinst Du recursively_translate mit Strings zu füttern, die Funktion erwartet aber ein Objekt, das ein content-Attribut hat. Für meta-Tags kannst Du also die Funktion nicht nutzen (macht ja auch keinen Sinn, denn hier gibt es nichts rekursives).

Auf oberster Ebene sollte kein ausführbarer Code stehen, der muß also auch noch in Funktionen wandern.
`files_from_folder` ist nur ein Folder und keine Files.
`findAll` ist veraltet, weil es sich nicht an die Namenskonvention hält, man benutzt `find_all`.
Man versucht erst, das Verzeichnis anzulegen, und dann darin eine Datei, statt den Code zum Dateischeiben zu doppeln.
An anderer Stelle hast Du doch schon gezeigt, dass Du weißt, dass man Pfade mit os.path.join zusammensetzt und nicht mit +. Warum machst Du das dann beim Schreiben?

Code: Alles auswählen

    if use_translate_folder:
        output_folder = os.path.join(directory, 'translated')
        os.makedirs(output_folder, exist_ok=True)
    else:
        output_folder = directory
     with open(os.path.join(output_folder, new_filename), 'w', encoding='utf-8') as html:
         html.write(soup[5:-6])
me_suzy
User
Beiträge: 8
Registriert: Dienstag 11. Oktober 2022, 08:03

ok, ich ändere den Kabeljau genau so, wie du es sagst

Bild

Code: Alles auswählen

from bs4 import BeautifulSoup
from bs4.formatter import HTMLFormatter
from googletrans import Translator
import requests
import pprint

translator = Translator()

class UnsortedAttributes(HTMLFormatter):
    def attributes(self, tag):
        for k, v in tag.attrs.items():
            yield k, v

files_from_folder = r"c:\carte\1"

use_translate_folder = True

destination_language = 'fr'

extension_file = ".html"

import os

directory = os.fsencode(files_from_folder)

def recursively_translate(node, translator):
    for contents in node.contents:
        if isinstance(contents, str): # which type is that?
            if contents.strip() != '':
                contents.replaceWith(translator.translate(contents, dest=destination_language).text)
        elif contents is not None:
            recursively_translate(contents, translator)

amount = 1
for file in os.listdir(directory):
    filename = os.fsdecode(file)
    print(filename)
    if filename == 'y_key_e479323ce281e459.html' or filename == 'directory.html':
        continue
    if filename.endswith(extension_file):
        with open(os.path.join(files_from_folder, filename), encoding='utf-8') as html:
            soup = BeautifulSoup('<pre>' + html.read() + '</pre>', 'html.parser')
            for title in soup.findAll('title'):
                recursively_translate(title)

            for meta in soup.findAll('meta', {'name':'description'}):
            
                #try:
                    #meta['content'] = translate.recursively_translate(meta['content'])
                    meta['content'] = recursively_translate(meta['content'])
                #except:
                    #pass
                    #print(e)


            for p in soup.findAll('p', class_='text_obisnuit2'):
                    recursively_translate(p)



        print(f'{filename} translated ({amount})')
        amount += 1
        soup = soup.encode(formatter=UnsortedAttributes()).decode('utf-8')
        new_filename = f'{filename.split(".")[0]}_{destination_language}.html'
        if use_translate_folder:
                output_folder = os.path.join(directory, 'translated')
                os.makedirs(output_folder, exist_ok=True)
        else:
                output_folder = directory
        with open(os.path.join(output_folder, new_filename), 'w', encoding='utf-8') as html:
                html.write(soup[5:-6])
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst dem recursively_translate von Sirius3 schon den translator mitgeben als Argument. Und bei einem einfachen Textattribut wie content macht recursive Uebersetzung keinen Sinn. Also direkt uebersetzen.
me_suzy
User
Beiträge: 8
Registriert: Dienstag 11. Oktober 2022, 08:03

__deets__ hat geschrieben: Dienstag 11. Oktober 2022, 11:27 Du musst dem recursively_translate von Sirius3 schon den translator mitgeben als Argument. Und bei einem einfachen Textattribut wie content macht recursive Uebersetzung keinen Sinn. Also direkt uebersetzen.
Ich weiß nicht, wie man das macht
Sirius3
User
Beiträge: 18278
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn Du das nicht weißt, mußt Du ein paar Schritte zurück gehen und erst einmal allgemein lernen was Funktionen sind, und wie man sie benutzt.
me_suzy
User
Beiträge: 8
Registriert: Dienstag 11. Oktober 2022, 08:03

change the part of code as this:

Code: Alles auswählen

            for meta in soup.findAll('meta', {'name':'description'}):
                try:
                    meta['content'] = translator.translate(meta['content'], dest=destination_language).text
                except:
                    pass
Benutzeravatar
__blackjack__
User
Beiträge: 14076
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Da ist schon wieder so eine falsche Ausnahmebehandlung.

Und man sollte vielleicht mal alle Namen die bei `bs4` benutzt werden und nicht der Python-Namenskonvention entsprechen durch die neueren Varianten austauschen, denn irgendwann werden sie die alten Namen entfernen. Also hier jetzt beispielsweise `findAll()` durch `find_all()`.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
me_suzy
User
Beiträge: 8
Registriert: Dienstag 11. Oktober 2022, 08:03

change this line:

Code: Alles auswählen

node.contents[x].replaceWith(translator.translate(node.contents[x], dest=destination_language).text)
then these lines:

Code: Alles auswählen

            for meta in soup.findAll('meta', {'name':'description'}):
                try:
                    meta['content'] = translator.translate(meta['content'], dest=destination_language).text
                except:
                    pass
---------------COPY THIS AND PASTE ON THE ORIGINAL CODE----------------------------

Code: Alles auswählen

def recursively_translate(node):
    for x in range(len(node.contents)):
        if isinstance(node.contents[x], str):
            if node.contents[x].strip() != '':
                try:
                    node.contents[x].replaceWith(translator.translate(node.contents[x], dest=destination_language).text)
                except:
                    pass
        elif node.contents[x] != None:
            recursively_translate(node.contents[x])

amount = 1
for file in os.listdir(directory):
    filename = os.fsdecode(file)
    print(filename)
    if filename == 'y_key_e479323ce281e459.html' or filename == 'directory.html':
        continue
    if filename.endswith(extension_file):
        with open(os.path.join(files_from_folder, filename), encoding='utf-8') as html:
            soup = BeautifulSoup('<pre>' + html.read() + '</pre>', 'html.parser')
            for title in soup.findAll('title'):
                recursively_translate(title)

            for meta in soup.findAll('meta', {'name':'description'}):
                try:
                    meta['content'] = translator.translate(meta['content'], dest=destination_language).text
                except:
                    pass
Antworten