2013-03-22 100 views
0

我有一個代碼,使用查詢和時間框架(可能會長達一年)從此newspaper檢索新聞結果。加速HTTP請求python和500錯誤

結果每頁分頁最多10篇文章,由於我找不到增加它的方法,我爲每個頁面發出請求,然後檢索每篇文章的標題,網址和日期。每個週期(HTTP請求和解析)需要30秒到1分鐘,這非常緩慢。最終它會停止響應代碼爲500.我想知道是否有辦法加速它或可能一次發出多個請求。我只是想檢索所有頁面中的文章細節。 下面是代碼:

import requests 
    import re 
    from bs4 import BeautifulSoup 
    import csv 

    URL = 'http://www.gulf-times.com/AdvanceSearchNews.aspx?Pageindex={index}&keywordtitle={query}&keywordbrief={query}&keywordbody={query}&category=&timeframe=&datefrom={datefrom}&dateTo={dateto}&isTimeFrame=0' 


    def run(**params): 
     countryFile = open("EgyptDaybyDay.csv","a") 
     i=1 
     results = True 
     while results: 
        params["index"]=str(i) 
        response = requests.get(URL.format(**params)) 
        print response.status_code 
        htmlFile = BeautifulSoup(response.content) 
        articles = htmlFile.findAll("div", { "class" : "newslist" }) 

        for article in articles: 
           url = (article.a['href']).encode('utf-8','ignore') 
           title = (article.img['alt']).encode('utf-8','ignore') 
           dateline = article.find("div",{"class": "floatright"}) 
           m = re.search("([0-9]{2}\-[0-9]{2}\-[0-9]{4})", dateline.string) 
           date = m.group(1) 
           w = csv.writer(countryFile,delimiter=',',quotechar='|', quoting=csv.QUOTE_MINIMAL) 
           w.writerow((date, title, url)) 

        if not articles: 
           results = False 
        i+=1 
     countryFile.close() 


    run(query="Egypt", datefrom="12-01-2010", dateto="12-01-2011") 

回答

1

這是一個很好的機會來嘗試gevent

對於request.get部分,您應該有一個單獨的例程,以便您的應用程序不必等待IO阻塞。

然後,你可以產生多個工人,並有隊列傳遞請求和文章。 也許與此類似:

import gevent.monkey 
from gevent.queue import Queue 
from gevent import sleep 
gevent.monkey.patch_all() 

MAX_REQUESTS = 10 

requests = Queue(MAX_REQUESTS) 
articles = Queue() 

mock_responses = range(100) 
mock_responses.reverse() 

def request(): 
    print "worker started" 
    while True: 
     print "request %s" % requests.get() 
     sleep(1) 

     try: 
      articles.put('article response %s' % mock_responses.pop()) 
     except IndexError: 
      articles.put(StopIteration) 
      break 

def run(): 
    print "run" 

    i = 1 
    while True: 
     requests.put(i) 
     i += 1 

if __name__ == '__main__': 
    for worker in range(MAX_REQUESTS): 
     gevent.spawn(request) 

    gevent.spawn(run) 
    for article in articles: 
     print "Got article: %s" % article 
+0

你也可以做到這一點與扭曲蟒蛇和遞延事件 – 2013-03-24 19:23:03

+0

的名單我現在認識到迭代可能實際的一篇文章中被發現之前停止。但你明白了 – baloo 2013-03-24 19:55:28

1

最有可能的放緩是在服務器,所以parallelising的http請求將着手對代碼的運行速度更快的最佳方式,雖然有很少的,你可以做,以加快啓動服務器響應。在IBM有一個很好的教程完成此

0

在我看來,你正在尋找一個飼料,這是報紙沒有刊登廣告。但是,這是一個以前已經解決的問題 - 有很多網站會爲您爲任意網站生成Feed,因此至少可以解決您的一個問題。其中一些需要一些人工指導,另一些則較少有機會進行調整,並且更自動化。

如果你完全可以避免自己做分頁和解析,我會推薦它。如果你不能,我簡單地使用gevent。也就是說,如果他們發回500的話,你的代碼可能不是什麼問題,增加並行性可能無濟於事。