Моя техника многопоточности неверна? - PullRequest
0 голосов
/ 28 марта 2012

Я пытаюсь написать программу, которая может одновременно загружать большое количество веб-страниц.Я хотел написать несколько небольших тестовых сценариев, чтобы понять, могу ли я понять многопоточность.Кажется, все работает хорошо, но не так стабильно или впечатляюще, как я себе представлял.Что я делаю неправильно?Как я могу улучшить это?

class UrlMiner(threading.Thread):
    def __init__(self, url_queue, targets, visited, timeout=5):
        threading.Thread.__init__(self)
        self.queue = url_queue
        self.targets = targets
        self.visited = visited
        self.timeout = timeout

    def run(self):
        while True:
            try:
                url = self.queue.get() 
                #print 'Scraping {}'.format(url)

                web_page = ''
                #with contextlib.closing(urllib2.urlopen(url, 
                #                                        None, 
                #                                        self.timeout)) as page:

                #    web_page = page.read()

                data = urllib2.urlopen(url, None, self.timeout)
                web_page = data.read()
                data.close()

            except urllib2.HTTPError:
                pass
            except urllib2.URLError:
                pass
            except socket.error:
                pass
            except socket.timeout: 
                pass
            except httplib.IncompleteRead:
                pass
            except httplib.BadStatusLine:
                pass
            except httplib.InvalidURL:
                pass   

            if web_page:
                #print 'Successfully scraped ', url
                self.visited.good()
            else:
                #print 'Unsuccessfully scraped ', url
                pass

            self.visited.add(url)
            self.queue.task_done() 


def main():
    urls = []
    with open('unvisited.txt') as infile:
        for line in infile:
            urls.append(line)

    visited = SetWrapper()
    targets = SetWrapper()

    queue = Queue.Queue()
    for url in urls:
        queue.put(url)

    # worker daemons
    for i in range(0, 100):
        t = UrlMiner(queue, targets, visited, timeout=14)
        t.setDaemon(True)
        t.start()

    start_time = time.time()
    queue.join()

    ttime = time.time() - start_time
    print '{} sites were scrapped in {} seconds'.format(len(urls), ttime)
    print '{} were filled requests.'.format(visited.goodv)

Результат для 100 потоков и 1001 сайтов выглядит следующим образом:

$ python test.py 1001 сайт был очищен за 138,261109114 секунд 262 былозаполненные запросы.

Чем меньше потоков я использую, тем быстрее и успешнее (больше заполненных запросов).У меня хорошее интернет-соединение, я проверил на OSX и Linux и получил те же результаты (8 ядер, 8 ГБ оперативной памяти).

...