8

出版物の Web ページを解析して著者を抽出する Web スクレーパーを作成しようとしています。Web ページの骨格構造は次のとおりです。

<html>
<body>
<div id="container">
<div id="contents">
<table>
<tbody>
<tr>
<td class="author">####I want whatever is located here ###</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

これまでのところ、このタスクを達成するために BeautifulSoup と lxml を使用しようとしましたが、2 つの div タグと td タグには属性があるため、どのように処理すればよいかわかりません。これに加えて、BeautifulSoup と lxml のどちらに頼るべきか、あるいは両方の組み合わせに頼るべきかわかりません。私は何をすべきか?

現時点では、私のコードは以下のようになります。

    import re
    import urllib2,sys
    import lxml
    from lxml import etree
    from lxml.html.soupparser import fromstring
    from lxml.etree import tostring
    from lxml.cssselect import CSSSelector
    from BeautifulSoup import BeautifulSoup, NavigableString

    address='http://www.example.com/'
    html = urllib2.urlopen(address).read()
    soup = BeautifulSoup(html)
    html=soup.prettify()
    html=html.replace('&nbsp', '&#160')
    html=html.replace('&iacute','&#237')
    root=fromstring(html)

多くの import ステートメントが冗長である可能性があることは認識していますが、現在持っているものをより多くのソース ファイルにコピーしただけです。

編集:私はこれを明確にしていないと思いますが、ページにスクレイピングしたいタグが複数あります。

4

4 に答える 4

12

divなぜタグについて心配する必要があるのか​​ 、あなたの質問からはわかりません。

soup = BeautifulSoup(html)
thetd = soup.find('td', attrs={'class': 'author'})
print thetd.string

あなたが与えるHTMLで、これを実行すると正確に出力されます:

####I want whatever is located here ###

これはあなたが望むもののようです。必要なものをより正確に指定できるかもしれませんが、この非常に単純なスニペットはそうではありません-考慮する必要があるtdすべてのクラスauthorの複数のタグ(すべて?一部だけ?どれ?)、そのようなタグが欠落している可能性があります(その場合はどうしたいですか)など。この単純な例と過剰なコードからだけでは、仕様が正確に何であるかを推測するのは困難です;-)。

編集:OPの最新のコメントに従って、そのようなtdタグが複数あり、作成者ごとに1つある場合:

thetds = soup.findAll('td', attrs={'class': 'author'})
for thetd in thetds:
    print thetd.string

...つまり、それほど難しくありません!-)

于 2009-09-08T03:01:06.553 に答える
6

または、BeautifulSoup が積極的に維持されなくなったため、pyquery を使用している可能性があります。http://www.crummy.com/software/BeautifulSoup/3.1-problems.html を参照してください。

まず、pyqueryをインストールします

easy_install pyquery

次に、スクリプトは次のように単純になります

from pyquery import PyQuery
d = PyQuery('http://mywebpage/')
allauthors = [ td.text() for td in d('td.author') ]

pyquery は jQuery でおなじみの css セレクター構文を使用しますが、これは BeautifulSoup よりも直感的です。下で lxml を使用しており、BeautifulSoup よりもはるかに高速です。しかし、BeautifulSoup は純粋な Python であるため、Google のアプリ エンジンでも動作します。

于 2010-05-02T07:01:44.100 に答える
5

lxml ライブラリは、Python で html を解析するための標準になりました。インターフェイスは最初はぎこちなく見えるかもしれませんが、それが何をするかについては非常に役に立ちます。

エスケープされた &entities; などの xml の特殊性をライブラリに処理させる必要があります。

import lxml.html

html = """<html><body><div id="container"><div id="contents"><table><tbody><tr>
          <td class="author">####I want whatever is located here, eh? &iacute; ###</td>
          </tr></tbody></table></div></div></body></html>"""

root = lxml.html.fromstring(html)
tds = root.cssselect("div#contents td.author")

print tds           # gives [<Element td at 84ee2cc>]
print tds[0].text   # what you want, including the 'í'
于 2011-05-04T10:51:34.193 に答える
1

BeautifulSoup は確かに正規の HTML パーサー/プロセッサです。しかし、一致させる必要があるこの種のスニペットだけがある場合は、HTML を表す階層オブジェクト全体を構築する代わりに、pyparsing を使用すると、より大きな検索式の作成の一部として、先頭と末尾の HTML タグを簡単に定義できます。

from pyparsing import makeHTMLTags, withAttribute, SkipTo

author_td, end_td = makeHTMLTags("td")

# only interested in <td>'s where class="author"
author_td.setParseAction(withAttribute(("class","author")))

search = author_td + SkipTo(end_td)("body") + end_td

for match in search.searchString(html):
    print match.body

Pyparsing の makeHTMLTags 関数は、出力"<tag>""</tag>"式だけではありません。また、次の処理も行います。

  • タグの大文字と小文字の一致
  • "<tag/>"構文
  • 開始タグに 0 個以上の属性
  • 任意の順序で定義された属性
  • 名前空間を持つ属性名
  • 一重引用符、二重引用符、または引用符なしの属性値
  • タグと記号の間、または属性名、「=」、および値の間の空白の介在
  • 名前付きの結果として解析した後、属性にアクセスできます

これらは、HTML スクレイピングに正規表現を使用することを検討する際の一般的な落とし穴です。

于 2009-09-08T03:31:52.450 に答える