Como obter o documento inteiro HTML como uma string?


237

Existe uma maneira no JS obter o HTML inteiro dentro das tags html , como uma string?

document.documentElement.??

10
A única resposta correta: stackoverflow.com/questions/817218/… ( interrompa a votação de respostas internas / externas em HTML, elas NÃO fornecem a fonte inteira! ) #
John

2
document.body.parentElement.innerHTML
Redwolf Programs

@ John, o que eles não fornecem?
bluejayke

Respostas:


320

A Microsoft adicionou as propriedades outerHTMLe innerHTMLhá algum tempo.

De acordo com a MDN , outerHTMLé suportado no Firefox 11, Chrome 0.2, Internet Explorer 4.0, Opera 7, Safari 1.3, Android, Firefox Mobile 11, IE Mobile, Opera Mobile e Safari Mobile. outerHTMLestá na especificação de análise e serialização do DOM .

Consulte quirksmode para compatibilidade do navegador para saber o que funcionará para você. Todo suporte innerHTML.

var markup = document.documentElement.innerHTML;
alert(markup);

28
outerHTML não recebe o doctype.
precisa saber é o seguinte

2
funcionou como um encanto! obrigado! existe alguma maneira de obter o tamanho de todos / todos os arquivos vinculados ao documento, incluindo os arquivos js e css?
www139 17/03/2015

@CMCDragonkai: Você pode obter o doctype separadamente e anexá-lo à string de marcação. Não é o ideal, eu sei, mas é possível.
21815 Mike Branski

76

Você pode fazer

new XMLSerializer().serializeToString(document)

em navegadores mais recentes que o IE 9

Consulte https://caniuse.com/#feat=xml-serializer


5
Esta foi a primeira resposta correta de acordo com os carimbos de data / hora. Partes da página, como a declaração XML, não serão incluídas e os navegadores manipularão o código ao usar as outras "respostas". Esta é a única postagem que deve ser votada com êxito (dos postados três dias depois). As pessoas precisam prestar atenção!
John

2
Isso não está totalmente correto, pois serializeToString executa uma codificação HTML. Por exemplo, se seu código contiver estilos que definem fontes como "Times New Roman", Times, serif, as aspas serão codificadas em html. Talvez isso não é importante para alguns de vocês, mas para mim é ...
Marko

3
@ John, o OP realmente pede "todo o HTML dentro das tags html". E a melhor resposta selecionada por Colin Burnett consegue isso. Essa resposta em particular (da Erik) incluirá as tags html e o doctype. Dito isto, este foi totalmente um diamante bruto para mim e exatamente o que eu estava procurando! O seu comentário ajudou muito porque me fez passar mais tempo com esta resposta, por isso obrigado :)
evanrmurphy

2
Eu acho que as pessoas devem ter cuidado com este, especificamente porque ele retorna um valor que não é o html real que seu navegador recebe. No meu caso, ele adicionou atributos à htmltag que o servidor nunca enviou :(
onassar

1
É suportado em todos os navegadores. Como esse navegador é ruim?
Erik Aigner

44

Eu acredito que document.documentElement.outerHTMLdeveria devolver isso para você.

De acordo com a MDN , outerHTMLé suportado no Firefox 11, Chrome 0.2, Internet Explorer 4.0, Opera 7, Safari 1.3, Android, Firefox Mobile 11, IE Mobile, Opera Mobile e Safari Mobile. outerHTMLestá na especificação de análise e serialização do DOM .

A página MSDN na outerHTMLpropriedade observa que ela é suportada no IE 5+. A resposta de Colin está vinculada à página do modo quirks do W3C, que oferece uma boa comparação da compatibilidade entre navegadores (para outros recursos do DOM também).


Nem todos os navegadores suportam isso.
Colin Burnett

@ Colin: Sim, bom ponto. Da experiência, eu me lembro que o IE 6+ e Firefox apoiá-lo, embora a página quirksmode é ligada sugere o contrário ...
Noldorin

O Firefox não suporta OuterHTML. É proprietário do IE. developer.mozilla.org/En/...
Jesse Dearing

4
Existe uma maneira de obter tudo, incluindo o doctype e as tags html?
trusktr

1
A minha foi a primeira, na verdade. : P
Noldorin 17/02

40

Eu tentei as várias respostas para ver o que é retornado. Estou usando a versão mais recente do Chrome.

A sugestão document.documentElement.innerHTML;retornou<head> ... </body>

A sugestão de Gaby document.getElementsByTagName('html')[0].innerHTML;retornou a mesma.

A sugestão document.documentElement.outerHTML;retornou, <html><head> ... </body></html> que é tudo à parte do 'doctype'.

Você pode recuperar o objeto doctype com document.doctype; Isso retorna um objeto, não uma string, portanto, se você precisar extrair os detalhes como strings para todos os doctypes até e incluindo HTML5, será descrito aqui: Obter DocType de um HTML como string com Javascript

Eu só queria HTML5, então o seguinte foi suficiente para criar o documento inteiro:

alert('<!DOCTYPE HTML>' + '\n' + document.documentElement.outerHTML);


6
Esta é a resposta mais completa e deve ser aceita. A partir de 2016, a compatibilidade do navegador está completa e não é mais necessário mencioná-la em detalhes (como na resposta atualmente aceita).
Dan Dascalescu 17/02

10

Você também pode fazer:

document.getElementsByTagName('html')[0].innerHTML

Você não receberá a tag Doctype ou html, mas tudo o mais ...



4

Provavelmente, ou seja:

>     webBrowser1.DocumentText

para FF acima de 1.0:

//serialize current DOM-Tree incl. changes/edits to ss-variable
var ns = new XMLSerializer();
var ss= ns.serializeToString(document);
alert(ss.substr(0,300));

pode funcionar em FF. (Mostra os MUITOS PRIMEIROS 300 caracteres desde o início de MUITO texto-fonte, principalmente doctype-defs.)

MAS esteja ciente de que o Diálogo normal "Salvar como" do FF NÃO PODE salvar o estado atual da página, e sim o X / h / tml-source-text originalmente carregado !! (um POST-up de ss para algum arquivo temporário e redirecionado para isso pode fornecer um texto-fonte salvável COM as alterações / edições anteriores feitas nele.)

Embora o FF surpreenda pela boa recuperação em "back" e por uma inclusão AGRADÁVEL de estados / valores em "Save (as) ..." para FIELDS, textarea etc., como entrada , não em elementos em contenteditable / designMode ...

Se NÃO for um xhtml- resp. xml-file (tipo MIME, NÃO apenas extensão-nome-de-arquivo!), pode-se usar document.open/write/close para definir o appr. conteúdo na camada de origem, que será salvo na caixa de diálogo de salvamento do usuário no menu Arquivo / Salvar do FF. Vejo: http://www.w3.org/MarkUp/2004/xhtml-faq#docwrite resp.

https://developer.mozilla.org/en-US/docs/Web/API/document.write

Neutro às questões de X (ht) ML, tente uma "view-source: http: // ..." como o valor do src-attrib de um iframe (feito por script !?), - para acessar um iframes- documento em FF:

<iframe-elementnode>.contentDocument, consulte google "mdn contentDocument" para aprox. membros, como 'textContent', por exemplo. - Consegui isso anos atrás e não gosto de rastejar por isso. Se ainda é urgente, mencione isso, que eu mergulhei ...




1

Para também deixar as coisas de fora da declaração <html>...</html>, mais importante <!DOCTYPE ...>, você pode percorrer document.childNodes, transformando cada uma delas em uma string:

const html = [...document.childNodes]
    .map(node => nodeToString(node))
    .join('\n') // could use '' instead, but whitespace should not matter.

function nodeToString(node) {
    switch (node.nodeType) {
        case node.ELEMENT_NODE:
            return node.outerHTML
        case node.TEXT_NODE:
            // Text nodes should probably never be encountered, but handling them anyway.
            return node.textContent
        case node.COMMENT_NODE:
            return `<!--${node.textContent}-->`
        case node.DOCUMENT_TYPE_NODE:
            return doctypeToString(node)
        default:
            throw new TypeError(`Unexpected node type: ${node.nodeType}`)
    }
}

Publiquei esse código como document-outerhtml no npm.


editar Observe que o código acima depende de uma função doctypeToString; sua implementação pode ser a seguinte (o código abaixo é publicado no npm como doctype-to-string ):

function doctypeToString(doctype) {
    if (doctype === null) {
        return ''
    }
    // Checking with instanceof DocumentType might be neater, but how to get a
    // reference to DocumentType without assuming it to be available globally?
    // To play nice with custom DOM implementations, we resort to duck-typing.
    if (!doctype
        || doctype.nodeType !== doctype.DOCUMENT_TYPE_NODE
        || typeof doctype.name !== 'string'
        || typeof doctype.publicId !== 'string'
        || typeof doctype.systemId !== 'string'
    ) {
        throw new TypeError('Expected a DocumentType')
    }
    const doctypeString = `<!DOCTYPE ${doctype.name}`
        + (doctype.publicId ? ` PUBLIC "${doctype.publicId}"` : '')
        + (doctype.systemId
            ? (doctype.publicId ? `` : ` SYSTEM`) + ` "${doctype.systemId}"`
            : ``)
        + `>`
    return doctypeString
}


0

Eu sempre uso

document.getElementsByTagName('html')[0].innerHTML

Provavelmente não é o caminho certo, mas posso entender quando o vejo.


Isso está incorreto porque não retornará a <html...>tag.
Dan Dascalescu 17/02

0

Eu só preciso do doctype html e deve funcionar bem no IE11, Edge e Chrome. Eu usei o código abaixo funciona bem.

function downloadPage(element, event) {
    var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);

    if ((navigator.userAgent.indexOf("MSIE") != -1) || (!!document.documentMode == true)) {
        document.execCommand('SaveAs', '1', 'page.html');
        event.preventDefault();
    } else {
        if(isChrome) {
            element.setAttribute('href','data:text/html;charset=UTF-8,'+encodeURIComponent('<!doctype html>' + document.documentElement.outerHTML));
        }
        element.setAttribute('download', 'page.html');
    }
}

e na sua âncora, use assim.

<a href="#" onclick="downloadPage(this,event);" download>Download entire page.</a>

Exemplo

    function downloadPage(element, event) {
    	var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
    
    	if ((navigator.userAgent.indexOf("MSIE") != -1) || (!!document.documentMode == true)) {
    		document.execCommand('SaveAs', '1', 'page.html');
    		event.preventDefault();
    	} else {
    		if(isChrome) {
                element.setAttribute('href','data:text/html;charset=UTF-8,'+encodeURIComponent('<!doctype html>' + document.documentElement.outerHTML));
    		}
    		element.setAttribute('download', 'page.html');
    	}
    }
I just need doctype html and should work fine in IE11, Edge and Chrome. 

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

<p>
<a href="#" onclick="downloadPage(this,event);"  download><h2>Download entire page.</h2></a></p>

<p>Some image here</p>

<p><img src="https://placeimg.com/250/150/animals"/></p>


0

Estou usando outerHTMLelementos (o <html>contêiner principal ) e XMLSerializerqualquer outra coisa, incluindo <!DOCTYPE>comentários aleatórios fora do <html>contêiner ou qualquer outra coisa que possa estar lá. Parece que o espaço em branco não é preservado fora do <html>elemento, então estou adicionando novas linhas por padrão com sep="\n".

function get_document_html(sep="\n") {
    let html = "";
    let xml = new XMLSerializer();
    for (let n of document.childNodes) {
        if (n.nodeType == Node.ELEMENT_NODE)
            html += n.outerHTML + sep;
        else
            html += xml.serializeToString(n) + sep;
    }
    return html;
}

console.log(get_document_html().slice(0, 200));


-2

Você precisa percorrer o documento childNodes e obter o conteúdoHTML externo.

no VBA, fica assim

For Each e In document.ChildNodes
    Put ff, , e.outerHTML & vbCrLf
Next e

Com isso, é possível obter todos os elementos da página da web, incluindo o nó <! DOCTYPE>, se existir


-9

A maneira correta é realmente:

webBrowser1.DocumentText

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.