Urllib2 & BeautifulSoup: Ładna para, ale za wolno - urllib3 i wątki?
Szukałem sposobu na zoptymalizowanie mojego kodu, gdy usłyszałem kilka dobrych rzeczy na temat wątków i urllib3. Najwyraźniej ludzie nie zgadzają się, które rozwiązanie jest najlepsze.
Problem z moim skryptem poniżej to czas wykonania: tak wolno!
Krok 1: Pobieram tę stronęhttp://www.cambridgeesol.org/institutions/results.php?region=Afghanistan&type=&BULATS=on
Krok 2: Analizuję stronę za pomocą BeautifulSoup
Krok 3: Dane umieściłem w dokumencie excela
Krok 4: Robię to jeszcze raz i jeszcze raz, i ponownie dla wszystkich krajów na mojej liście (duża lista) (zmieniam tylko „Afganistan” w adresie URL na inny kraj)
Oto mój kod:
<code>ws = wb.add_sheet("BULATS_IA") #We add a new tab in the excel doc x = 0 # We need x and y for pulling the data into the excel doc y = 0 Countries_List = ['Afghanistan','Albania','Andorra','Argentina','Armenia','Australia','Austria','Azerbaijan','Bahrain','Bangladesh','Belgium','Belize','Bolivia','Bosnia and Herzegovina','Brazil','Brunei Darussalam','Bulgaria','Cameroon','Canada','Central African Republic','Chile','China','Colombia','Costa Rica','Croatia','Cuba','Cyprus','Czech Republic','Denmark','Dominican Republic','Ecuador','Egypt','Eritrea','Estonia','Ethiopia','Faroe Islands','Fiji','Finland','France','French Polynesia','Georgia','Germany','Gibraltar','Greece','Grenada','Hong Kong','Hungary','Iceland','India','Indonesia','Iran','Iraq','Ireland','Israel','Italy','Jamaica','Japan','Jordan','Kazakhstan','Kenya','Kuwait','Latvia','Lebanon','Libya','Liechtenstein','Lithuania','Luxembourg','Macau','Macedonia','Malaysia','Maldives','Malta','Mexico','Monaco','Montenegro','Morocco','Mozambique','Myanmar (Burma)','Nepal','Netherlands','New Caledonia','New Zealand','Nigeria','Norway','Oman','Pakistan','Palestine','Papua New Guinea','Paraguay','Peru','Philippines','Poland','Portugal','Qatar','Romania','Russia','Saudi Arabia','Serbia','Singapore','Slovakia','Slovenia','South Africa','South Korea','Spain','Sri Lanka','Sweden','Switzerland','Syria','Taiwan','Thailand','Trinadad and Tobago','Tunisia','Turkey','Ukraine','United Arab Emirates','United Kingdom','United States','Uruguay','Uzbekistan','Venezuela','Vietnam'] Longueur = len(Countries_List) for Countries in Countries_List: y = 0 htmlSource = urllib.urlopen("http://www.cambridgeesol.org/institutions/results.php?region=%s&type=&BULATS=on" % (Countries)).read() # I am opening the page with the name of the correspondant country in the url s = soup(htmlSource) tableGood = s.findAll('table') try: rows = tableGood[3].findAll('tr') for tr in rows: cols = tr.findAll('td') y = 0 x = x + 1 for td in cols: hum = td.text ws.write(x,y,hum) y = y + 1 wb.save("%s.xls" % name_excel) except (IndexError): pass </code>
Wiem więc, że wszystko nie jest idealne, ale czekam na nowe rzeczy w Pythonie! Skrypt jest bardzo wolny, ponieważ urllib2 nie jest tak szybki, a BeautifulSoup. W przypadku zupy chyba nie mogę tego zrobić lepiej, ale dla urllib2 nie.
EDYTUJ 1:Wieloprocesowość bezużyteczna z urllib2? Wydaje się być interesujący w moim przypadku. Co myślicie o tym potencjalnym rozwiązaniu ?!
<code># Make sure that the queue is thread-safe!! def producer(self): # Only need one producer, although you could have multiple with fh = open('urllist.txt', 'r'): for line in fh: self.queue.enqueue(line.strip()) def consumer(self): # Fire up N of these babies for some speed while True: url = self.queue.dequeue() dh = urllib2.urlopen(url) with fh = open('/dev/null', 'w'): # gotta put it somewhere fh.write(dh.read()) </code>
EDYCJA 2: URLLIB3 Czy ktoś może mi powiedzieć coś więcej na ten temat?
Użyj ponownie tego samego połączenia gniazda dla wielu żądań (HTTPConnectionPool i HTTPSConnectionPool) (z opcjonalną weryfikacją certyfikatu po stronie klienta).https://github.com/shazow/urllib3
O ile proszę o 122 razy tę samą stronę dla różnych stron, myślę, że ponowne użycie tego samego połączenia z gniazdem może być interesujące, czy się mylę? Nie może być szybciej? ...
<code>http = urllib3.PoolManager() r = http.request('GET', 'http://www.bulats.org') for Pages in Pages_List: r = http.request('GET', 'http://www.bulats.org/agents/find-an-agent?field_continent_tid=All&field_country_tid=All&page=%s' % (Pages)) s = soup(r.data) </code>