web-dev-qa-db-fra.com

Comment pouvez-vous convertir par programme (ou avec un outil) des fichiers mhtml .MHT en fichiers HTML et CSS normaux?

De nombreux outils permettent d'exporter un fichier .MHT. Je veux un moyen de convertir ce fichier unique en une collection de fichiers, un fichier HTML, les images pertinentes et des fichiers CSS, que je pourrais ensuite télécharger sur un hébergeur et être consommable par tous les navigateurs. Quelqu'un connaît-il des outils, des bibliothèques ou des algorithmes pour le faire?.

18
klumsy

Eh bien, vous pouvez ouvrir le fichier .MHT dans IE et la page Web Save it as aa. J'ai testé cela avec cette page, et même s'il semblait étrange dans IE (c'est IE après tout), il a enregistré puis s'est bien ouvert dans Chrome (comme dans, il semblait qu'il devrait)).

À l'exception de cette méthode, en regardant le fichier lui-même, les blocs de texte sont enregistrés dans le fichier tel quel et tout autre contenu est enregistré dans Base64. Chaque élément de contenu est précédé de:

[Boundary]
Content-Type: [Mime Type]
Content-Transfer-Encoding: [Encoding Type]
Content-Location: [Full path of content]

[Type MIME], [Type d'encodage] et [Chemin complet du contenu] sont variables. [Type d'encodage] semble être base64 ou imprimable entre guillemets . [Limite] est défini au début du fichier .MHT comme ceci:

From: <Saved by WebKit>
Subject: converter - How can you programmatically (or with a tool) convert .MHT mhtml        files to regular HTML and CSS files? - Stack Overflow
Date: Fri, 9 May 2013 13:53:36 -0400
MIME-Version: 1.0
Content-Type: multipart/related;
    type="text/html";
    boundary="----=_NextPart_000_0C08_58653ABB.B67612B7"

En utilisant cela, vous pouvez créer votre propre analyseur de fichiers si nécessaire.

12
XNargaHuntress

Outre IE et MS Word, il existe un programme multiplateforme open source appelé 'mht2html' écrit pour la première fois en 2007 et mis à jour pour la dernière fois en 2016 =. Il possède à la fois une interface graphique et une interface de terminal.

Je ne l'ai pas encore testé mais il semble avoir reçu de bonnes critiques.

3
sahwar

Le fichier MHT est essentiellement MIME. Il est donc possible d'utiliser Chilkat.Mime ou des composants System.Net.Mime entièrement gratuits pour accéder à sa structure interne. Si, par exemple, MHT contient des images, elles peuvent être remplacées par des chaînes base64 dans le code HTML de sortie.

Imports HtmlAgilityPack
Imports Fizzler.Systems.HtmlAgilityPack
Imports Chilkat
Public Function ConvertMhtToHtml(ByVal mhtFile As String) As String
    Dim chilkatWholeMime As New Chilkat.Mime
    'Load mime'
    chilkatWholeMime.LoadMimeFile(mhtFile)
    'Get html string, which is 1-st part of mime'
    Dim html As String = chilkatWholeMime.GetPart(0).GetBodyDecoded
    'Create collection for storing url of images and theirs base64 representations'
    Dim allImages As New Specialized.NameValueCollection
    'Iterate through mime parts'
    For i = 1 To chilkatWholeMime.NumParts - 1
        Dim m As Chilkat.Mime = chilkatWholeMime.GetPart(i)
        'See if it is image'
        If m.IsImage AndAlso m.Encoding = "base64" Then
            allImages.Add(m.GetHeaderField("Content-Location"), "data:" + m.ContentType + ";base64," + m.GetBodyEncoded)
        End If : m.Dispose()
    Next : chilkatWholeMime.Dispose()
    'Now it is time to replace the source attribute of all images in HTML with dataURI'
    Dim htmlDoc As New HtmlDocument : htmlDoc.LoadHtml(html) : Dim docNode As HtmlNode = htmlDoc.DocumentNode
    For i = 0 To allImages.Count - 1
        'Select all images, whose src attribute is equal to saved URL'
        Dim keyURL As String = allImages.GetKey(i) 'Saved url from MHT'
        Dim elementsWithPics() As HtmlNode = docNode.QuerySelectorAll("img[src='" + keyURL + "']").ToArray
        Dim imgsrc As String = allImages.GetValues(i)(0) 'dataURI as base64 string'
        For j = 0 To elementsWithPics.Length - 1
            elementsWithPics(j).SetAttributeValue("src", imgsrc)
        Next
        'Select all elements, whose style attribute contains saved URL'
        elementsWithPics = docNode.QuerySelectorAll("[style~='" + keyURL + "']").ToArray
        For j = 0 To elementsWithPics.Length - 1
            'Get and modify style'
            Dim modStyle As String = Strings.Replace(elementsWithPics(j).GetAttributeValue("style", String.Empty), keyURL, imgsrc, 1, 1, 1)
            elementsWithPics(j).SetAttributeValue("style", modStyle)
        Next : Erase elementsWithPics
    Next
    'Get final html'
    Dim tw As New StringWriter()
    htmlDoc.Save(tw) : html = tw.ToString : tw.Close() : tw.Dispose()
    Return html
End Function
3
Zagavarr

Je pense que @ XGundam05 est correct. Voici ce que j'ai fait pour que ça marche.

J'ai commencé avec un projet Windows Form dans Visual Studio. Ajout du WebBrowser au formulaire, puis ajout de deux boutons. Alors ce code:

    private void button1_Click(object sender, EventArgs e)
    {
        webBrowser1.ShowSaveAsDialog();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        webBrowser1.Url = new Uri("localfile.mht");
    }

Vous devriez pouvoir prendre ce code et ajouter une liste de fichiers et traiter chacun avec un foreach. webBrowser contient une méthode appelée ShowSaveAsDialog(); Et cela permettra d'enregistrer en tant que .mht ou simplement le html ou la page complète.

EDIT: vous pouvez utiliser le document WebBrowser et gratter les informations à ce stade. En ajoutant un richTextBox et une variable publique selon MS ici: http://msdn.Microsoft.com/en-us/library/ms171713.aspx

    public string Code
    {
        get
        {
            if (richTextBox1.Text != null)
            {
                return (richTextBox1.Text);
            }
            else
            {
                return ("");
            }
        }
        set
        {
            richTextBox1.Text = value;
        }
    }


    private void button2_Click(object sender, EventArgs e)
    {
        webBrowser1.Url = new Uri("localfile.mht");
        HtmlElement elem;

        if (webBrowser1.Document != null)
        {

            HtmlElementCollection elems = webBrowser1.Document.GetElementsByTagName("HTML");
            if (elems.Count == 1)
            {
                elem = elems[0];
                Code = elem.OuterHtml;
                foreach (HtmlElement elem1 in elems)
                {
                    //look for pictures to save
                }

            }
        }
    }
1
CaptainBli

Donc, automatiser IE était difficile et inutilisable de bout en bout, donc je pense que construire une sorte de code qui le fera sera la voie à suivre. Sur github, j'ai trouvé ceci python celui qui peut être bon

https://github.com/Modified/MHTifierhttp://decodecode.net/elitist/2013/ 01/mhtifier/

Si j'ai le temps, j'essaierai de faire quelque chose de similaire dans PowerShell.

0
klumsy