2011-11-08 83 views
5


因此,我相對較新的python,爲了學習,我已經開始編寫一個程序,上線到維基百科,找到第一個鏈接在概述部分的隨機文章,遵循該鏈接並繼續前進,直到它進入循環或找到哲學頁面(詳見here),然後以指定次數重複執行新過程。然後我想以某種形式的有用數據結構收集結果,以便我可以使用Rpy library將數據傳遞給R,以便我可以繪製某種網絡圖(R非常擅長繪製類似的東西)代表所訪問頁面的圖中的節點以及從起始文章到哲學頁面的路徑。Wikipedia哲學遊戲圖在Python和R

所以我沒有問題讓python從wiki返回相當結構化的html,但有一些問題,我不明白。到目前爲止,我已經從lxml庫中選擇了使用cssselector的第一個鏈接。它選擇用於第一鏈路(在一個標籤)是p標籤的直系後代,即帶有class =「MW-內容-LTR」 div標籤的直系後代這樣的:

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,但這似乎是一個非常笨重的解決方案,我認爲可能有一些我沒有想到的更好的東西。

因此,目前我將結果存儲在列表中。所以我有一個名爲paths的列表,其中有一些列表包含了包含wiki文章標題的字符串。

問題的第二部分是: 如何遍歷此列表以表示多個收斂路徑?像這樣存儲結果是一個好主意嗎?由於末端圖應該看起來像是一個顛倒的樹,所以我考慮製作某種樹類,但對於概念上相當簡單的東西來說,這看起來像是很多工作。

任何想法或建議將不勝感激。
乾杯,
戴維

+0

請不要在一箇中發佈兩個不同的問題! – 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

我就回答第二個問題:

一開始,只是保持一個字典映射一個維基百科的文章標題下。這將使您能夠輕鬆快速地檢查您是否已經點擊過您之前找到的文章。基本上這只是存儲一個有向圖的頂點,它們的起點索引。

如果你已經達到了Python字典效率不夠高的地步(它確實有很大的內存開銷,一旦有數百萬個項目的內存可能成爲問題),你可以找到一個更有效的圖形數據結構來適應您的需求。

編輯

好吧,我回答第一個問題,以及...

在第一部分,我強烈建議使用MediaWiki API,而不是領的HTML版本,並解析它。該API可以查詢某些類型的鏈接,例如只是維基鏈接或只是跨語言鏈接。另外,這個API有Python client libraries,它應該簡化Python代碼。

如果網站的HTML提供了一個全面且有據可查的API,就不要解析它!

+0

整個英語維基百科小於4M的文章。您可以將4M隨機50字節字符串插入到散列中,以檢查解釋器是否可以輕鬆處理它。 –

1

在第一部分,這是不可能找到與CSS選擇器托架,因爲就在html關注括號只是文本。

如果我是你,我會使用選擇器來查找對遊戲有效的所有相關段落元素。然後,我會查看段落元素的文本,並刪除無效的任何內容 - 例如,括號內的任何內容以及斜體標記之間的任何內容。然後,我會爲我需要的鏈接元素搜索這個處理過的文本。這比手動處理整個html文檔略好一些。

我不確定我是否確切地遵循了第二部分的內容,而是將此搜索的結果表示爲一棵樹:在尋找週期時,這是一個壞主意, t代表。

對於數據結構,我會列出'節點',其中一個節點表示一個頁面,並且具有一個URL和一個發生次數。然後,我會使用強力算法來比較節點列表 - 如果兩個列表的節點相同,則可以合併它們,從而增加每個鏡像節點的「發生次數」。

我不會使用標準的python'list',因爲它不能自行循環。也許創建你自己的鏈表實現來包含節點。