Beautiful Soupに完全な形式のドキュメントを渡したら、解析されたデータ構造は、元のドキュメントと全く同じに見えます。しかし、ドキュメントに何か問題がある場合、Beautiful Soupはデータ構造に対して、合理的な構造を見つけ出すために、ヒューリスティックを使用します。
HTMLの解析
HTMLドキュメントを解析するために、Beautiful Soupクラスを使用します。ここでは、
BeautifulSoup
が知っていることをいくつか示します:- ネスト出来るタグ(<BLOCKQUOTE>)があり 、出来ないタグ(<P>)がある。
- Table タグと list タグには、自然なネストの順序がある。例えば、
<TD> タグは <TR> タグ中にあり、それ以外の箇所では使われない。
- <SCRIPT> タグの中身はHTMLとして解析されるべきではない。
- <META> タグはドキュメントのエンコーディングを指定するかもしれない。
from BeautifulSoup import BeautifulSoup html = "<html><p>Para 1<p>Para 2<blockquote>Quote 1<blockquote>Quote 2" soup = BeautifulSoup(html) print soup.prettify() # <html> # <p> # Para 1 # </p> # <p> # Para 2 # <blockquote> # Quote 1 # <blockquote> # Quote 2 # </blockquote> # </blockquote> # </p> # </html>
BeautifulSoup
は、たとえ元のドキュメントに終了タグがなくても、終了タグを置くのにふさわしい場所を見つけることに注意してください。元のドキュメントは正しいHTMLではありませんが、それほど悪いHTMLでもありません。
ここに、本当にひどいドキュメントがあります。
終了タグの欠落以外の問題の中でも、 <FORM>タグが <TABLE>タグの外側で始まり、 <TABLE>タグの中で終了しています(このようなHTMLは主なweb企業によって運営されているウェブサイトで見つけられます。)
from BeautifulSoup import BeautifulSoup html = """ <html> <form> <table> <td><input name="input1">Row 1 cell 1 <tr><td>Row 2 cell 1 </form> <td>Row 2 cell 2<br>This</br> sure is a long cell </body> </html>"""Beautiful Soupは、このドキュメントも同様に処理します:
print BeautifulSoup(html).prettify() # <html> # <form> # <table> # <td> # <input name="input1" /> # Row 1 cell 1 # </td> # <tr> # <td> # Row 2 cell 1 # </td> # </tr> # </table> # </form> # <td> # Row 2 cell 2 # <br /> # This # sure is a long cell # </td> # </html>テーブルの最後のセルが <TABLE> タグの外側にあります;
Beautiful Soupは、 <FORM> タグを閉じる時、 <TABLE> タグを閉じることを決定します。
おそらく、元のドキュメントの著者は、 <FORM> タグがテーブルの終わりまで拡張されると考えたのでしょう、しかし、Beautiful Soupはそのことを知る由もありません。
このような変な場合でも、Beautiful Soupは不良ドキュメントを解析し、全てのデータにアクセスできるようにしてくれます。
XMLの解析
BeautifulSoup
クラスは、HTML作者の意図を推測するため、webブラウザのようにヒューリスティックがたくさんあります。しかし、 XML は修正タグの集合を持っておらず、そのため、これらのヒューリスティックは適用されません。したがって、
BeautifulSoup
は、 XML をうまく扱えません. XML ドキュメントを解析するためには、
BeautifulStoneSoup
クラスを使ってください。BeautifulStoneSoup
は、あらゆるXML方言についての特別な知識がいらず、タグのネストについての極めて単純なルールを持つ、一般的なクラスです:ここで、実際の動作をご覧ください:
from BeautifulSoup import BeautifulStoneSoup xml = "<doc><tag1>Contents 1<tag2>Contents 2<tag1>Contents 3" soup = BeautifulStoneSoup(xml) print soup.prettify() # <doc> # <tag1> # Contents 1 # <tag2> # Contents 2 # </tag2> # </tag1> # <tag1> # Contents 3 # </tag1> # </doc>
BeautifulStoneSoup
の最も一般的な欠点は、自己終了タグを知らないことです。HTML は、自己終了タグの修正集合を持っていますが、 XML では、DTD が何と言っているかに依ります。
自己終了タグ名を、
selfClosingTags
引数としてコンストラクタに渡すことで、BeautifulStoneSoup
に、特定のタグが自己終了タグだと教えることが出来ます:from BeautifulSoup import BeautifulStoneSoup xml = "<tag>Text 1<selfclosing>Text 2" print BeautifulStoneSoup(xml).prettify() # <tag> # Text 1 # <selfclosing> # Text 2 # </selfclosing> # </tag> print BeautifulStoneSoup(xml, selfClosingTags=['selfclosing']).prettify() # <tag> # Text 1 # <selfclosing /> # Text 2 # </tag>
動作しない場合には
これら2つとは異なるヒューリスティックを持つ他の解析クラスもあります。また、解析木をサブクラス化、カスタマイズ出来、解析木に自分のヒューリスティックを渡すことも出来ます。
0 件のコメント:
コメントを投稿