2

これはPython2.7.2の簡単なコードで、サイトをフェッチし、指定されたサイトからすべてのリンクを取得します。

import urllib2
from bs4 import BeautifulSoup

def getAllLinks(url):
    response = urllib2.urlopen(url)
    content = response.read()
    soup = BeautifulSoup(content, "html5lib")
    return soup.find_all("a")

links1 = getAllLinks('http://www.stanford.edu')
links2 = getAllLinks('http://med.stanford.edu/')

print len(links1)
print len(links2)

問題は、2番目のシナリオでは機能しないことです。102と0を出力しますが、2番目のサイトには明確なリンクがあります。BeautifulSoupは解析エラーをスローせず、マークアップを正常に出力します。おそらく、med.stanford.eduのソースからの最初の行が原因であると思われます。これはxmlであると言っています(content-typeはtext / htmlですが):

<?xml version="1.0" encoding="iso-8859-1"?>

それを無視するようにBeautifulを設定する方法、または回避策がわかりません。デフォルトのマークアップに問題があったため、パーサーとしてhtml5libを使用しています(マークアップが正しくありません)。

4

2 に答える 2

3

ドキュメントがXMLであると主張する場合、lxmlパーサーが最良の結果をもたらすことがわかります。コードを試してみましたが、html5libの代わりにlxmlパーサーを使用すると、300個のリンクが見つかります。

于 2012-04-22T22:54:40.650 に答える
2

<?xml...あなたは問題が線であるということは正確に正しいです。それを無視するのは非常に簡単です。コンテンツの最初の行をスキップして、

    content = response.read()

のようなもので

    content = "\n".join(response.readlines()[1:])

この変更により、len(links2)300になります。

ETA:おそらく条件付きでこれを実行したいので、コンテンツの最初の行を常にスキップするとは限りません。例は次のようになります。

content = response.read()
if content.startswith("<?xml"):
    content = "\n".join(content.split("\n")[1:])
于 2012-04-22T17:00:27.043 に答える