2011-04-12 74 views
4

我剛剛完成了我的第一個python腳本,一個來自philipines的選舉數據的刮板。我沒有編程背景,我已經使用stata進行統計分析,並且最近在R中涉及了一些,因爲我想在某個時刻切換。但我想學習python從網站和其他來源提取數據。到目前爲止,我只瀏覽python教程,O'Reilly的「Learning Python」正在我的書架上等待。我通過從其他人的腳本中獲取靈感並瀏覽包含的軟件包文檔,編寫了以下腳本。第一個python腳本,刮板,建議歡迎

我基本上尋找的是一般性建議。該腳本確實有效,但是有沒有多餘的部分?我應該以不同的結構嗎?有沒有典型的(或簡單的啞巴)初學者的錯誤?

我自己編寫了幾個問題,我已經在腳本之後列出了。

import mechanize 
import lxml.html 
import csv 

site = "http://www.comelec.gov.ph/results/2004natl/2004electionresults_local.aspx" 

br = mechanize.Browser() 
response = br.open(site) 

output = csv.writer(file(r'output.csv','wb')) 


br.select_form(name="ctl00") 
provinces = br.possible_items("provlist") 

for prov in provinces: 
    br.select_form(name="ctl00") 
    br["provlist"] = [prov] 
    response = br.submit() 
    br.select_form(name="ctl00") 
    pname = str(br.get_value_by_label("provlist")).strip("[]") 
    municipalities = br.possible_items("munlist") 
    for mun in municipalities: 
     br.select_form(name="ctl00") 
     br["munlist"] = [mun] 
     response = br.submit(type="submit", name="ctl01") 
     html = response.read() 
     root = lxml.html.fromstring(html) 
     try: 
      table = root.get_element_by_id(id="dlistCandidates") 
      data = [ 
         [td.text_content().strip() for td in row.findall("td")] 
         for row in table.findall('tr') 
        ] 
     except KeyError: 
      print "Results not available yet." 
      data = [ [ "." for i in range(5) ] ] 
     br.select_form(name="ctl00") 
     mname = str(br.get_value_by_label("munlist")).strip('[]') 
     print pname, mname, data, "\n" 
     for row in data: 
      if row: 
       row.append(pname) 
       row.append(mname) 
       output.writerow([s.encode('utf8') if type(s) is unicode else s for s in row]) 
  1. 當我執行該腳本,我得到一個錯誤信息「DeprecationWarning:[item.name在self.items項目]是什麼原因,我應該擔心它

  2. 我現在循環遍歷省份的數字鍵,然後每次都取這個名字,我應該在開始時建立一個字典並且循環遍歷它嗎?

  3. 有沒有簡單的方法來編碼「ene」字符N),直接到正常N?

  4. 每次都沒有更換「數據」,我該如何最好地收集所有內容,然後在最後寫入一個csv文件?這是更好的解決方案嗎?

  5. 該網站需要相當長的時間來響應每個請求。獲取所有數據大約需要一個小時。我可以通過執行一些腳本和連接省份列表來加快速度。我將如何去發送一個腳本中的並行請求?我最終希望從該網站獲取更多數據,並且加速此過程將會很好。

  6. 我已經嘗試了BeautifulSoup和lxml模塊,但更喜歡lxml解決方案。哪些其他模塊通常對這些類型的任務有用?

  7. 是否有用於內置模塊和其他文檔/幫助文件的中央註冊表?在我看來,那些到處散落的文件,這有點不方便。寫作幫助(某事)往往導致「找不到東西」。

任何建議和批評都非常感謝。英語不是我的母語,但我希望我能夠至少保持錯誤。

+0

7.幫助(東西),導致「未找到的東西」。根本沒有文件通常是一個壞模塊的跡象;往往避免它們。或者貢獻文檔。 – smci 2011-07-14 18:35:36

回答

6
  1. DeprecationWarningmechanize模塊來了,當你調用possible_items被髮出。這意味着更好的方式來獲得相同的效果。我不知道作者爲什麼沒有把它更明確。

  2. 我不認爲它有什麼區別。

  3. 你可能想看看http://effbot.org/zone/unicode-convert.htm

  4. 逐漸寫作,正如你所做的那樣,對我來說看起來很好。你可以創建一個行列表,在你的循環中追加它,然後在最後一次寫完所有的東西;主要優勢是模塊化略有增加。 (假設你想做同樣的拼湊,但以另一種方式使用結果;你可以更容易地重用你的代碼。)

  5. (a)如果遠程站點需要很長時間來響應,從那個遠程站點,你確定並行地打多個請求實際上會有所幫助嗎? (b)您可能想要檢查相關網站的所有者是否反對這種欺詐行爲,既不禮貌也不反對,因爲如果他們反對,他們可能會注意到您正在做的事情並阻止您。我猜想,因爲這是一個政府網站,他們可能會用它。 (c)查看Python標準庫中的threadingmultiprocessing模塊。

  6. 我不知道;抱歉。

  7. 號(除非你指望谷歌。)

看起來,如果你做了一下腰 - 向前來確定省市。如果它們在腳本的調用之間沒有變化,那麼可能值得將它們保存在本地的某處,而不是每次都詢問遠程網站。 (增益可能不值得花時間 - 但你可能需要測量獲得這些信息需要多長時間。)

你可能會考慮提取將代碼轉換爲候選列表的代碼(如果是這樣的話)分成一個單獨的功能。

你可以考慮提取這樣的事情到一個單獨的功能:

def select_item(br, form, listname, value, submit_form=None): 
    br.select_form(form) 
    br[listname] = [value] 
    return br.submit(type="submit", name=(submit_form or form)) 

,也許是這樣的:

def get_name(br, formname, label): 
br.select_form(formname) 
    return str(br.get_value_by_label(label)).strip("[]")