質問
BeautifulSoupを使用してhtmlページを解析しようとしていますが、BeautifulSoupはHTMLやそのページをまったく気に入らないようです。以下のコードを実行すると、メソッドprettify()はページのスクリプトブロックのみを返します(以下を参照)。なぜそれが起こるのか誰にも分かりますか?
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()
これは、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>
ありがとう!
更新:最新のように見える次のバージョンを使用しています。
__author__ = "Leonard Richardson (leonardr@segfault.org)"
__version__ = "3.1.0.1"
__copyright__ = "Copyright (c) 2004-2009 Leonard Richardson"
__license__ = "New-style BSD"
解決
<!>#321; ukasz 提案。 BeautifulSoup 3.1はPython 3.0と互換性があるように設計されていたため、パーサーをSGMLParserからHTMLParserに変更する必要がありました。
<!> quot; Beautiful Soupは、Python 3で廃止されたSGMLParserではなくHTMLParserに基づいています。SGMLParserで処理されたHTMLがいくつかありますが、HTMLParserでは<!> quot;
他のヒント
lxml をお試しください。名前にもかかわらず、HTMLの解析とスクレイピングにも使用されます。 BeautifulSoupよりもはるかに高速で、<!> quot; broken <!> quot;も処理します。 BeautifulSoupよりもHTMLが優れているため、より適切に機能する可能性があります。 lxml APIを学習したくない場合は、BeautifulSoupの互換性APIもあります。
BeautifulSoupを使用する理由はありません。ただし、Google App Engineまたは純粋にPython以外のものが許可されていない場合を除きます。
BeautifulSoupは魔法ではありません。受信するHTMLがひどい場合、機能しません。
この場合、着信HTMLはまさにそれです。BeautifulSoupが何をすべきかを判断するには壊れすぎています。たとえば、次のようなマークアップが含まれています。
SCRIPT type = <!> quot; <!> quot; javascript <!> quot; <!> quot;
(二重引用符に注意してください。)
BeautifulSoupのドキュメントには、BeautifulSoupがマークアップを解析できない場合にできることのセクションが含まれています。これらの代替案を調査する必要があります。
Samj:もし私が
HTMLParser.HTMLParseError: bad end tag: u"</scr' + 'ipt>"
BeautifulSoupにサービスを提供する前に、犯人をマークアップから削除するだけです。
html = urllib2.urlopen(url).read()
html = html.replace("</scr' + 'ipt>","")
soup = BeautifulSoup(html)
次のコードの解析にも問題がありました:
<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:不正な終了タグ:u ''、26行目、127列目
サム
BeautifulSoupバージョン '3.0.7a'でこのスクリプトをテストし、正しい出力と思われるものを返します。 「3.0.7a」と「3.1.0.1」の間で何が変わったのかわかりませんが、試してみてください。
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()
上記のステートメントを実行すると、HTMLページ全体が返されます。