2013-03-22 2 views
0

У меня есть код, который извлекает новости из этого newspaper с использованием запроса и временного интервала (может быть до года).ускорить запрос HTTP-запроса python и 500

Результаты разбиты на страницы до 10 статей на странице, и поскольку я не мог найти способ увеличить его, я выдаю запрос для каждой страницы, затем получаю заголовок, URL-адрес и дату каждой статьи. Каждый цикл (HTTP-запрос и синтаксический анализ) занимает от 30 секунд до минуты, и это очень медленно. И в конечном итоге он остановится с кодом ответа 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, так что вашему приложению не придется ждать блокировки ввода-вывода.

Затем вы можете создать нескольких сотрудников и иметь очереди для передачи запросов и статей. Может быть что-то похожее на это:

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

вы также можете сделать это с помощью витой питона и список отложенных событий –

+0

теперь я понимаю, что итерация может остановиться до фактического последней статьи найден. Но ты получил идею – baloo

1

Наиболее вероятно, замедлится является сервер, так parallelising запросы HTTP будет лучший способ пойти о том, чтобы код работать быстрее, хотя есть очень мало вы можете сделать, чтобы ускорить ответ сервера. Есть хороший учебник на IBM для этого точно

0

Мне кажется, что вы ищете питание, который, что газета не рекламирует. Тем не менее, это проблема, которая была решена до этого - есть много сайтов, которые будут генерировать каналы для вас для произвольного веб-сайта, чтобы хотя бы решить одну из ваших проблем. Некоторые из них требуют некоторого человеческого руководства, а другие имеют меньше возможностей для настройки и более автоматизированы.

Если вы можете вообще не выполнять разбиение на страницы и синтаксический анализ, я бы рекомендовал его. Если вы этого не сделаете, я воспользуюсь gevent для простоты. Тем не менее, если они отправят вас назад на 500, ваш код, скорее всего, будет менее проблематичным, и добавление параллелизма может не помочь.

Смежные вопросы