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