Pergunta

Estou tentando analisar uma página HTML com o BeautifulSoup, mas parece que o BeautifulSoup não gosta do HTML ou daquela página. Quando eu executo o código abaixo, o método prettify () me retorna apenas o bloco de script da página (veja abaixo). Alguém tem uma ideia por que isso acontece?

import urllib2
from BeautifulSoup import BeautifulSoup

url = "http://www.futureshop.ca/catalog/subclass.asp?catid=10607&mfr=&logon=&langid=FR&sort=0&page=1"
html = "".join(urllib2.urlopen(url).readlines())
print "-- HTML ------------------------------------------"
print html
print "-- BeautifulSoup ---------------------------------"
print BeautifulSoup(html).prettify()

A saída é produzida por BeautifulSoup.

-- BeautifulSoup ---------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script language="JavaScript">
 <!--
     function highlight(img) {
       document[img].src = "/marketing/sony/images/en/" + img + "_on.gif";
     }

     function unhighlight(img) {
       document[img].src = "/marketing/sony/images/en/" + img + "_off.gif";
     }
//-->
</script>

Obrigado!

ATUALIZAÇÃO: Estou usando a versão a seguir, que parece ser a mais recente.

__author__ = "Leonard Richardson (leonardr@segfault.org)"
__version__ = "3.1.0.1"
__copyright__ = "Copyright (c) 2004-2009 Leonard Richardson"
__license__ = "New-style BSD"
Foi útil?

Solução

Tente com a versão 3.0.7a como Łukasz sugerido. O BeautifulSoup 3.1 foi projetado para ser compatível com o Python 3.0, então eles tiveram que mudar o analisador do SGMLPARSER para HTMLPARSER, que parece mais vulnerável ao HTML ruim.

De Changelog para o BeautifulSoup 3.1:

"A bela sopa agora é baseada em htmlparser, em vez de sgmlparser, que se foi no python 3. Há algum html ruim que o SGMLPARSER manuseou, mas o htmlparser não"

Outras dicas

Tentar lxml. Apesar do nome, é também para analisar e raspar o HTML. É muito, muito mais rápido que o BeautifulSoup, e até lida com o HTML "quebrado" melhor do que o BeautifulSoup, para que possa funcionar melhor para você. Ele também possui uma API de compatibilidade para o BeautifulSoup, se você não quiser aprender a API LXML.

Ian Blicking concorda.

Não há mais razão para usar o BeautifulSoup, a menos que você esteja no Google App Engine ou algo em que algo não puramente não é permitido.

BeautifulSoup não é mágico: se o HTML de entrada é horrível demais, não vai funcionar.

Nesse caso, o HTML recebido é exatamente isso: muito quebrado para o BeautifulSoup descobrir o que fazer. Por exemplo, ele contém marcação como:

Script Type = "" JavaScript ""

(Observe a citação dupla.)

Os documentos do BeautifulSoup contém uma seção o que você pode fazer se o belo GreatSoup não puder analisar sua marcação. Você precisará investigar essas alternativas.

Samj: Se eu conseguir coisas comoHTMLParser.HTMLParseError: bad end tag: u"</scr' + 'ipt>"Acabei de remover o culpado da marcação antes de servi -lo para o BeautifulSoup e tudo é Dandy:

html = urllib2.urlopen(url).read()
html = html.replace("</scr' + 'ipt>","")
soup = BeautifulSoup(html)

Eu tive problemas para analisar o seguinte código também:

<script>
        function show_ads() {
          document.write("<div><sc"+"ript type='text/javascript'src='http://pagead2.googlesyndication.com/pagead/show_ads.js'></scr"+"ipt></div>");
        }
</script>

Htmlparseerror: tag de final ruim: u '', na linha 26, coluna 127

Sam

Eu testei este script na versão do BeautifulSoup '3.0.7a' e ele retorna o que parece ser a saída correta. Não sei o que mudou entre '3.0.7a' e '3.1.0.1', mas experimente.

import urllib
from BeautifulSoup import BeautifulSoup

>>> page = urllib.urlopen('http://www.futureshop.ca/catalog/subclass.asp?catid=10607&mfr=&logon=&langid=FR&sort=0&page=1')
>>> soup = BeautifulSoup(page)
>>> soup.prettify()

No meu caso, executando as instruções acima, ele retorna toda a página HTML.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top