2

我試圖以編程刮所有的紐約馬拉松賽的數據在這裏找到:http://web2.nyrrc.org/cgi-bin/htmlos.cgi/2112.6.038135231510781094到CSV。Webscraping與BeautifulSoup - 紐約馬拉松時報

兩個問題:

  1. 我不能想出一個辦法來遍歷所有不同年份,而無需手動提供對應於一個單一的一年,各年齡組0-99的URL。
  2. 只是專注於單一的URL(相當於一年的數據),我的代碼不會發現任何表。

    def scrapeTime(url): 
     
        f = urllib.urlopen(url) 
     
        s = f.read() 
     
        print " read: ", len(s), " bytes" 
     
        f.close() 
     
    
     
        soup = BeautifulSoup(s) 
     
        print soup 
     
        
     
        #iterate over all rows 
     
        for row in table.findAll('tr'): 
     
         col = row.findAll('td') 
     
         FirstName=col[0].string # first column should have rank of runner 
     
         LastName=col[1].string 
     
    
     
    
     
    def main(): 
     
        url2013 = "http://web2.nyrrc.org/cgi-bin/htmlos.cgi/2112.12.076919132010781094" 
     
        scrapeTime(url2013)
    如果我只是打印的「湯」的內容,輸出的樣子:
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> 
     
        <html><head> 
     
        <title>302 Found</title> 
     
        </head><body> 
     
        <h1>Found</h1> 
     
        <p>The document has moved <a href="http://web2.nyrrc.org/cgi-bin/htmlos.cgi/33272.1.016990806717006432">here</a>.</p> 
     
        </body></html>
    除了我可以在瀏覽器中查看URL,只是沒有通過Python的。我懷疑這與提供標題有關?

回答

3

您需要填寫搜索表單並解析結果。你需要更多的自動化。

下面是使用mechanize庫的解決方案。我已經添加評論,但讓我知道如果您對代碼有任何疑問:

from bs4 import BeautifulSoup 
import mechanize 

url = "http://web2.nyrrc.org/cgi-bin/start.cgi/mar-programs/archive/archive_search.html" 

browser = mechanize.Browser() 
browser.addheaders = [ 
    ('user-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3'), 
    ('accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8') 
] 
browser.set_handle_robots(False) 

# get years 
browser.open(url) 
browser.form = list(browser.forms())[0] 
select = browser.form.controls[3] 
years = [item.name for item in select.get_items()] 

# process year by year 
for year in years: 
    print "Processing year=" + year 

    # open up search form again, fill out an appropriate year and submit 
    browser.open(url) 
    browser.form = list(browser.forms())[0] 
    select = browser.form.controls[3] 

    browser.form['input.searchyear'] = [year] 
    browser.form['search.method'] = ['search.flat'] 
    browser.submit() 

    # get overall winners 
    soup = BeautifulSoup(browser.response()) 
    print soup.find(text='Overall Winners').parent.parent.parent.find_next_sibling('tr').find('pre').text 

它打印:

Processing year=2013 

    Men GEOFFREY MUTAI, Kenya   2:08:24 
Women PRISCAH JEPTOO, Kenya   2:25:07 

Processing year=2011 

    Men GEOFFREY MUTAI, Kenya   2:05:06 
Women FIREHIWOT DADO, Ethiopia  2:23:15 

... 

基本上,它開闢了一個搜索表單,讓所有可能的從select下拉列表中選擇了幾年。然後,它逐年提交表格並使用BeautifulSoup分析結果。

+0

有時我得到的錯誤,'URLError:<錯誤的urlopen [錯誤10060]連接嘗試失敗,因爲連接的方沒有正確一段時間後響應或已建立的連接失敗,因爲連接的主機沒有respond.'任何想法會導致什麼? – Parseltongue 2014-09-19 05:10:51

+0

@Parseltongue可能這是因爲撞擊的部位過於頻繁的。嘗試在請求之間添加延遲('time.sleep()')。 – alecxe 2014-09-19 05:40:27