Estaba buscando una manera de optimizar mi código cuando escuché algunas cosas buenas sobre los hilos y urllib3. Aparentemente, las personas no están de acuerdo sobre qué solución es la mejor.Urllib2 & BeautifulSoup: Buena pareja pero demasiado lento - urllib3 & threads?
El problema con mi script a continuación es el tiempo de ejecución: ¡tan lento!
Paso 1: I buscar a esta página http://www.cambridgeesol.org/institutions/results.php?region=Afghanistan&type=&BULATS=on
Paso 2: I analizar la página con BeautifulSoup
Paso 3: puse los datos en un doc excel
Paso 4: Lo vuelvo a hacer, una y otra vez para todos los países de mi lista (lista grande) (Estoy cambiando "Afganistán" en la url a otro país)
Aquí está mi código:
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
así que sé que no todo es perfecto, pero estoy deseando volver a aprender cosas nuevas en Python! El script es muy lento porque urllib2 no es tan rápido y BeautifulSoup. Para la sopa, creo que realmente no puedo hacerlo mejor, pero para urllib2, no lo hago.
EDITAR 1: Multiprocessing useless with urllib2? Parece ser interesante en mi caso. ¿Qué piensan ustedes acerca de esta posible solución?
# 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())
EDIT 2: URLLIB3 Puede alguien decirme más cosas acerca de eso?
Re-use the same socket connection for multiple requests (HTTPConnectionPool and HTTPSConnectionPool) (with optional client-side certificate verification). https://github.com/shazow/urllib3
Por lo que yo estoy solicitando 122 veces el mismo sitio web para diferentes páginas, supongo reutilizar la misma conexión de socket puede ser interesante, ¿me equivoco? ¿No puede ser más rápido? ...
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)
Sí, su problema aquí es que la búsqueda es de un solo hilo. Pero si usa el multihilo, tendrá que hacer que el proceso de escritura para sobresalir sea seguro. Recomiendo scrapy, un framework de raspado para Python, que hace todo por ti. – WooParadog
Muchas gracias, veré lo que Scrapy puede hacer por mí. Y urllib3 tampoco es una solución válida? :) Pero si hay alguna posibilidad de hacerlo más rápido sin usar scrapy, será mejor que yo. ¡Estoy aprendiendo Python así que me gustaría entender todo! –
No debe abrir más de una conexión al mismo sitio web, creo que es más como un "acuerdo de caballero" –