0

クエリと時間枠(最大1年)を使用してこの新聞からニュース結果を取得するコードがあります。

結果は1ページあたり最大10の記事にページ分割され、それを増やす方法が見つからなかったため、各ページにリクエストを発行してから、各記事のタイトル、URL、日付を取得します。各サイクル(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")
4

5 に答える 5

1

最も遅くなるのはサーバーであるため、サーバーの応答を高速化するためにできることはほとんどありませんが、httpリクエストを並列化することが、コードの実行を高速化するための最良の方法です。これを正確に行うための優れたチュートリアルがIBMにあります

于 2013-03-24T18:57:18.727 に答える
1

これは、 geventを試す良い機会です。

アプリケーションがIOブロッキングを待つ必要がないように、request.get部分には別のルーチンが必要です。

次に、複数のワーカーを生成し、リクエストや記事を渡すためのキューを作成できます。多分これに似たもの:

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
于 2013-03-24T19:04:30.300 に答える
0

あなたはその新聞が宣伝していないフィードを探しているように私には思えます。ただし、これは以前に解決された問題です。任意のWebサイトのフィードを生成するサイトが多数あるため、少なくとも1つの問題を解決できます。これらの中には、人間による指導が必要なものもあれば、微調整の機会が少なく、より自動化されているものもあります。

ページネーションを実行したり、自分で解析したりすることをまったく回避できる場合は、それをお勧めします。できない場合はgevent、簡単にするために2番目に使用します。とは言うものの、彼らがあなたに500を返送しているのであれば、あなたのコードはおそらく問題ではなく、追加された並列処理は役に立たないかもしれません。

于 2013-03-26T20:49:49.993 に答える
0

すべての呼び出しを非同期で行うことができます。

これを見てください:http: //pythonquirks.blogspot.in/2011/04/twisted-asynchronous-http-request.html

ツイストではなくgeventを使用することもできますが、オプションを指示するだけです。

于 2013-03-27T10:51:10.197 に答える
0

これはあなたが探しているものに非常によく近づくかもしれません。

Pythonを介して複数のHTTPリクエストを送信するための理想的な方法は?[複製]

ソースコード: https ://github.com/kennethreitz/grequests

于 2013-03-29T23:56:51.353 に答える