2011-11-08 10 views
5


私は比較的新しいpythonです。学習するために、私はウィキペディアにオンラインで行くプログラムを書いて、ランダムの概要セクションの最初のリンクを見つけましたそれがループに入るか、または哲学ページ(詳細はhere)を見つけて、指定された回数だけ新しいランダム記事のためにこのプロセスを繰り返すまで、そのリンクをたどり続けます。私は有用なデータ構造の形で結果を集めて、Rpy libraryを使ってRにデータを渡すことができるように、ネットワークダイアグラムを描画することができますノードは訪問されたページを表す図内のノードと、出発記事から哲学ページに至る経路とを示している。ウィキペディアの哲学のゲームダイアグラム、パイソンとR

だから、私はpythonでかなり構造化されたhtmlをwikiから返すことに問題はありませんが、私が分かりづらい問題がいくつかあります。これまでは、lxmlライブラリのcssselectorを使って最初のリンクを選択しました。それは、このようなクラス=「MW-コンテンツ-LTR」とdivタグの直接の子孫である、APタグの直接の子孫である(タグにおいて)最初のリンクのための選択:

user_agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT)' 
    values = {'name' : 'David Kavanagh', 
     'location' : 'Belfast', 
     'language' : 'Python' } 
    headers = { 'User-Agent' : user_agent } 
    encodes = urllib.urlencode(values) 
    req = urllib2.Request(url, encodes, headers) 
    page = urllib2.urlopen(req) 
    root = parse(page).getroot() 
    return root.cssselect("div.mw-content-ltr>p>a")[0].get('href') 

このコードは、ページ内の最初のリンクを見つけるために使用する関数内にあります。それはほとんどの部分で動作しますが、最初のリンクが他のタグの中にある場合、問題は、pタグの直接的な子孫ではなく、bタグなどと言います。上記のwikiの記事からわかるように、イタリック体またはカッコ内のリンクはゲームに適格ではありません。つまり、イタリック体のリンクは得られませんが、括弧内のリンクが頻繁に得られます。椅子の記事の最初のリンクのようなページの最初のリンクが表示されない場合がありますが、太字で表示されています。私は直系の子孫規定を削除しようとしましたが、概要セクションの上にあるリンク、通常はサイドボックス、pタグ、表の概要セクションと同じdivにあるリンクを頻繁に取得します。

だから私の質問の最初の部分は次のとおりです。

にはどうすればカッコ内のか、イタリック体ではなく、概要セクションの最初のリンクを選択するためにcssselectorsまたはいくつかの他の関数やライブラリを使用することができます。私は正規表現を使って生のhtmlを調べることを考えましたが、それは非常に厄介な解決策のように思えます。私は思っていないより少し良いものがあるかもしれないと思っていました。

現在、私は結果をリストのリストに保存しています。だから私は、wikiの記事のタイトルを含む文字列を含むリストがある、パスと呼ばれるリストがあります。

質問の2番目の部分は次のとおりです。 複数の収束パスを表すためにこのリストのリストをトラバースするにはどうすればよいですか?このような結果を保存するのは良い考えですか?終わりの図は逆さまの木のように見えるはずなので、私はいくつかの種類のツリーを作ることを考えましたが、それは概念的に、かなり単純なもののための多くの仕事のようです。

ご意見やご提案をいただければ幸いです。
乾杯、
デイビー

+0

2つの異なる質問を1つに投稿しないでください! – taleinat

+1

美しいスープはHTMLをよりよく解析できます(IMO)。 BSオブジェクトには、ネストされたタグやタグの属性(HTMLタグの意味)を返す属性(オブジェクト指向の意味)があります。シンチでなければならない。 **これまでにHTMLを解析するために正規表現を使用しないでくださいhttp://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – aitchnyu

答えて

4

私はちょうど2番目の質問にお答えします。これは簡単かつ迅速にチェックすることができますあなたはすでにあなたが以前に見つけた記事をヒットしました。本質的に、これは有向グラフの頂点をその起点によってインデックスされたものとして保存するだけです。

Python dictが十分に効率的ではない(かなりのメモリオーバーヘッドがありますが、アイテム数が何百万にも達するとメモリに問題が発生する可能性がある)場合は、より効率的なグラフデータ構造を見つけることができますあなたの要望。 [OK]を

EDIT

、私は...だけでなく最初の部分については

を最初の質問にお答えします、私は非常にHTMLのバージョンを取得し、それを解析するのではなく、MediaWiki APIを使用することをお勧めします。 APIを使用すると、特定の種類のリンク、たとえばWiki間リンクや言語間リンクなどのクエリを実行できます。さらに、このAPIにはPython client librariesがあります。これは、Pythonコードから単純に使用する必要があります。

ウェブサイトのHTMLが包括的かつ十分に文書化されたAPIを提供している場合、解析しないでください。

+0

英語のウィキペディア全体4M記事未満です。インタプリタが簡単に処理できるかどうかを確認するために、4Mランダム50バイト文字列をハッシュに挿入するプロトタイプを作成できます。 –

1

最初の部分のために限り、HTMLなどの懸念ブラケットは単なるテキストですされているので、それは、CSSセレクタとブラケットを発見することはできません。

私があなたの場合は、セレクタを使用して、ゲームに有効なすべての関連する段落要素を検索します。次に、段落要素のテキストを見て、括弧で囲まれたものやイタリックタグ間のものなど、無効なものを削除します。次に、この処理されたテキストで必要なリンク要素を検索します。これは、HTML文書全体を手動で処理するよりもやや面白いです。

私は、2番目の部分のために何をしているのか正確にはわかりませんが、この検索の結果をツリーとして表現するのは確かではありません:これはサイクルを探しているときの悪い考えです。 tは表す。

データ構造では、ノードがページを表し、発生数がある「ノード」のリストがあります。私はその後、ブルートフォースアルゴリズムを使ってノードのリストを比較します.2つのリストに同じノードがある場合は、それらをマージして、ミラーリングされた各ノードの「発生回数」を増やすことができます。

これはループバックできないので、私は標準のpython 'list'を使用しません。おそらく、ノードを格納するための独自のリンクリストの実装を作成します。すぐ隣にdictのマッピング1 Wikipediaの記事のタイトルを保持し、スタートのために

関連する問題