2013-06-16 11 views
5

Mam plik z ponad 160.000 adresów URL, z których stron chcę skrobać niektóre informacje. Skrypt wygląda mniej więcej tak:Scrape 160.000 stron - zbyt wolny

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) 

Który działa, ale bardzo, bardzo wolno. Zgarnianie wszystkich 160 000 stron zajęłoby więcej niż cztery dni. Jakieś sugestie, aby to przyspieszyć?

+2

Wykorzystanie wielowątkowości lub asynchroniczne żądania HTTP biblioteki jak [grequests] (https://github.com/kennethreitz/grequests) – Blender

+2

Albo użyć Scrappy. http://scrapy.org/ – Darek

+0

Dzięki za sugestie, ale nie mam pojęcia, jak korzystać z grecksts lub scrapy. Jestem wielkim początkującym pytonem ... – ticktack

Odpowiedz

2

Kilka rad na kodzie:

Podczas kompilowania wzorzec regex, upewnij się też używać obiektów skompilowanych. I unikaj kompilowania wyrażenia regularnego w każdej pętli przetwarzania.

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

Jeśli chcesz uniknąć korzystania z innych ram, najlepszym rozwiązaniem, aby przyspieszyć go więc użyć biblioteki standardowy wątków w celu uzyskania wielu połączeń HTTP wykraczających równolegle.

coś takiego:

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, wielkie dzięki! To działa jak urok! – ticktack

Powiązane problemy