2012-03-14 14 views
1

私はPythonでHTMLParserクラスを使用して基本的なWebクローラーを開発しています。PythonのHTMLParserを使用して特定のリンクを抽出する方法

def handle_starttag(self, tag, attrs): 
    if tag == 'a': 
     for (key, value) in attrs: 
      if key == 'href': 
       newUrl = urljoin(self.baseUrl, value) 
       self.links = self.links + [newUrl] 

私はにページ上のすべてのリンクを見つけたいと思ったとき、これは非常によく働いていた:私はこのようになります修正のhandle_starttag方法と私のリンクを取得します。今私は特定のリンクを取得したいだけです。 HTMLParserは、ドキュメントの一部を取得することを意味し、SAXスタイルやストリーミングパーサーです

<td class="title"><a href="http://www.stackoverflow.com">StackOverflow</a><span class="comhead"> (arstechnica.com) </span></td> 
+0

タグのクラス名がtitleであるかどうかを確認してください。 – vireshas

+0

これをどうお勧めしますか? – initWithStyle

+1

Pythonのlxmlライブラリをチェックアウトしましたか?それはページ上のリンクや他の要素をかなり効率的に解析することができます。 http://lxml.de/ – dangerChihuahua007

答えて

6

:どのように私はこれだけのように、<td class="title"></td>タグの間にあるリンクを取得するに行くか

それらは解析されますが、一度にすべての文書は解析されません。パーサーは、タグや他のタイプのデータを処理するために提供するメソッドを呼び出します。どのタグが他のタグの中にあるかなど、あなたが興味を持っている可能性のあるコンテキストは、通過したタグから収集する必要があります。

たとえば、<td>タグが表示されている場合、あなたは表のセルにいることがわかり、その効果を示すフラグを設定できます。 </td>が表示されたら、テーブルセルを残してそのフラグをクリアできることがわかります。テーブルセル内のリンクを取得するには、<a>が表示され、テーブルセル内にあることがわかっている場合(設定したフラグのため)、タグのhref属性の値を取得します。

from HTMLParser import HTMLParser 

class LinkExctractor(HTMLParser): 

    def reset(self): 
     HTMLParser.reset(self) 
     self.extracting = False 
     self.links  = [] 

    def handle_startag(self, tag, attrs): 
     if tag == "td" or tag == "a": 
      attrs = dict(attrs) # save us from iterating over the attrs 
     if tag == "td" and attrs.get("class", "") == "title": 
      self.extracting = True 
     elif tag == "a" and "href" in attrs and self.extracting: 
      self.links.append(attrs["href"]) 

    def handle_endtag(self, tag): 
     if tag == "td": 
      self.extracting = False 

これはすぐにあなたは、人々がlxmlBeautifulSoupを推薦している理由である文書から、あなたが望む結果を得るために、より多くのコンテキストを必要と苦痛であることを取得します。これらはDOMスタイルのパーサで、ドキュメントの階層を追跡し、DOM API、XPath、CSSセレクタなどのさまざまな使い方をナビゲートできます。

最近、私は同様の質問に最近hereと答えました。

+2

私は 'dict(attr)'の代わりに、他のすべての投稿のように 'if'を使って暗黙の' for'の代わりに使うことを提案できたなら、2回upvoteします。 – szczurcio

関連する問題