Я пытаюсь написать программу, которая может одновременно загружать большое количество веб-страниц.Я хотел написать несколько небольших тестовых сценариев, чтобы понять, могу ли я понять многопоточность.Кажется, все работает хорошо, но не так стабильно или впечатляюще, как я себе представлял.Что я делаю неправильно?Как я могу улучшить это?
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 ГБ оперативной памяти).