2013-06-16 18 views
5

Ho un file con più di 160.000 url, di cui pagine voglio racimolare alcune informazioni. Lo script ha un aspetto approssimativo:Scrape 160.000 pagine - troppo lento

htmlfile = urllib2.urlopen(line) 
htmltext = htmlfile.read() 
regexName = '"></a>(.+?)</dd><dt>' 
patternName = re.compile(regexName) 
name = re.findall(patternName,htmltext) 
if name: 
    text = name[0] 
else: 
    text = 'unknown' 

nf.write(text) 

Che funziona, ma molto, molto lento. Ci vorranno più di quattro giorni per racimolare tutte le 160.000 pagine. Qualche suggerimento per accelerarlo?

+2

Utilizzare il multithreading o un asincrono libreria di richieste HTTP come [grequests] (https://github.com/kennethreitz/grequests) – Blender

+2

Oppure utilizzare Scrappy. http://scrapy.org/ – Darek

+0

Grazie per i tuoi suggerimenti, ma non ho idea di come usare grequetsts o scrapy. Sono un grande principiante di Python ... – ticktack

risposta

2

Alcuni consigli sul vostro codice:

Quando si compila il modello di espressione regolare, assicurarsi di utilizzare anche l'oggetto compilato. Evita di compilare la tua espressione regolare in ogni ciclo di elaborazione.

pattern = re.compile('"></a>(.+?)</dd><dt>') 
# ... 
links = pattern.findall(html) 

Se si vuole evitare l'uso di altri framework, la soluzione migliore per accelerare le cose in modo utilizzare la libreria standard di threading al fine di ottenere più connessioni HTTP che vanno in parallelo.

Qualcosa di simile a questo:

from Queue import Queue 
from threading import Thread 

import urllib2 
import re 

# Work queue where you push the URLs onto - size 100 
url_queue = Queue(10) 
pattern = re.compile('"></a>(.+?)</dd><dt>') 

def worker(): 
    '''Gets the next url from the queue and processes it''' 
    while True: 
     url = url_queue.get() 
     print url 
     html = urllib2.urlopen(url).read() 
     print html[:10] 
     links = pattern.findall(html) 
     if len(links) > 0: 
      print links 
     url_queue.task_done() 

# Start a pool of 20 workers 
for i in xrange(20): 
    t = Thread(target=worker) 
    t.daemon = True 
    t.start() 

# Change this to read your links and queue them for processing 
for url in xrange(100): 
    url_queue.put("http://www.ravn.co.uk") 

# Block until everything is finished. 
url_queue.join() 
+0

Wow, grazie mille amico! Funziona come un incantesimo! – ticktack

Problemi correlati