5

私は今、ウェブページの解析に美しいスープを使用しています。それは非常に有名で良いと聞きましたが、正しく機能していないようです。

これが私がしたことです

import urllib2
from bs4 import BeautifulSoup

page = urllib2.urlopen("http://www.cnn.com/2012/10/14/us/skydiver-record-attempt/index.html?hpt=hp_t1")
soup = BeautifulSoup(page)
print soup.prettify()

これは簡単なことだと思います。ウェブページを開いて、beautifulsoupに渡します。しかし、これが私が得たものです:

Warning (from warnings module):

File "C:\Python27\lib\site-packages\bs4\builder\_htmlparser.py", line 149

"Python's built-in HTMLParser cannot parse the given document. This is not a bug in Beautiful Soup. The best solution is to install an external parser (lxml or html5lib), and use Beautiful Soup with that parser. See http://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-a-parser for help."))

...

HTMLParseError: bad end tag: u'</"+"script>', at line 634, column 94

CNNのウェブサイトはうまく設計されるべきだと思ったので、何が起こっているのかよくわかりません。誰かがこれについて考えていますか?

4

4 に答える 4

10

ドキュメントから:

可能であれば、速度を上げるために lxml をインストールして使用することをお勧めします。Python 2 の 2.7.3 より前のバージョン、または Python 3 の 3.2.2 より前のバージョンを使用している場合は、lxml または html5lib をインストールすることが不可欠です。Python の組み込み HTML パーサーは、古いバージョンではあまり良くありません。バージョン。

Python 2.7 でより堅牢なパーサー (lxml や html5lib など) をインストールすると、コードはそのまま (Python 2.7、Python 3.3 で) 動作します。

try:
    from urllib2 import urlopen
except ImportError:
    from urllib.request import urlopen # py3k

from bs4 import BeautifulSoup # $ pip install beautifulsoup4

url = "http://www.cnn.com/2012/10/14/us/skydiver-record-attempt/index.html?hpt=hp_t1"
soup = BeautifulSoup(urlopen(url))
print(soup.prettify())

HTMLParser.py - より堅牢な SCRIPT タグの解析バグが関連している可能性があります。

于 2012-10-14T21:54:34.797 に答える
8

BeautifulSoup や HTML パーサーを使用して Web ページを読み取ることはできません。Web ページが整形式のドキュメントであるという保証はありません。この特定のケースで何が起こっているのかを説明しましょう。

そのページには、次のインライン JavaScript があります。

var str="<script src='http://widgets.outbrain.com/outbrainWidget.js'; type='text/javascript'></"+"script>";

スクリプト タグをページに配置する文字列を作成していることがわかります。さて、あなたが HTML パーサーなら、これを扱うのは非常に難しいことです。突然<script>タグにヒットすると、トークンの読み取りに進みます。残念ながら、これを行った場合:

<script>
alert('hello');
<script>
alert('goodby');

ほとんどのパーサーは、「わかりました。開いているスクリプト タグを見つけました」と言うでしょう。おっと、別のオープン スクリプト タグを見つけました。彼らは最初のものを閉じるのを忘れていたに違いありません! そして、パーサーは両方とも有効なスクリプトであると考えます。

したがって、この場合、BeautifulSoup は<script>タグを認識し、それがjavascript 文字列内にあるにもかかわらず、有効な開始タグである可能性があるように見え、BeautifulSoup にも発作があります。

文字列をもう一度見ると、彼らがこの興味深い作業を行っていることがわかります。

... "</" + "script>";

これは奇妙に思えますよね?str = " ... </script>"余分な文字列連結を行わずにそのまま実行した方がよいのではないでしょうか? これは実際には、パーサーが壊れないようにするための一般的なトリックです (スクリプト タグを文字列として記述する愚かな人々による、悪い習慣です)。これを行う場合:

var a = '</script>';

インライン スクリプトでは、パーサーがやって来て、</script>スクリプト タグ全体が終了したことを実際に確認して判断し、そのスクリプト タグの残りのコンテンツをプレーン テキストとしてページにスローします。これは、JS 構文が無効であっても、技術的には終了スクリプト タグをどこにでも配置できるためです。パーサーの観点からは、HTML コードを JavaScript としてレンダリングしようとするよりも、早い段階でスクリプト タグから抜け出したほうがよいでしょう。

したがって、通常の HTML パーサーを使用して Web ページを解析することはできません。非常に危険なゲームです。整形式の HTML が得られるという保証はありません。何をしようとしているかに応じて、正規表現を使用してページのコンテンツを読み取るか、ヘッドレス ブラウザーで完全にレンダリングされたページ コンテンツを取得してみてください。

于 2012-10-14T21:41:32.867 に答える
2

BeautifulSoupでhtml5libパーサーを使用する必要があります

reqd パーサーをインストールするには、pip を使用します。

pip install html5lib

次に、そのパーサーをこのように使用します

import mechanize
br = mechanize.Browser()
html = br.open("http://google.com/",timeout=100).read()
soup = BeautifulSoup(html,'html5lib')
a_s = soup.find_all('a')
for i in range(0,len(a_s)):
 print a_s[i]['href']
于 2014-09-04T08:50:36.670 に答える