2013-06-10 6 views
12

मैं scrapy का उपयोग कर एक बहुत ही सरल वेब स्क्रैपर के साथ 23770 वेबपृष्ठों को स्क्रैप कर रहा हूं। मैं स्केपर और यहां तक ​​कि अजगर के लिए काफी नया हूं, लेकिन नौकरी करने वाले मकड़ी को लिखने में कामयाब रहा। हालांकि, यह वास्तव में धीमा है (23770 पृष्ठों को क्रॉल करने में लगभग 28 घंटे लगते हैं)।वेब स्क्रैपर को गति दें

मैंने scrapy वेबपृष्ठ और मेलिंग सूचियों और stackoverflow पर देखा है, लेकिन मुझे शुरुआती लोगों के लिए समझने योग्य तेज़ क्रॉलर लिखने के लिए सामान्य अनुशंसाएं नहीं मिल रही हैं। शायद मेरी समस्या मकड़ी नहीं है, लेकिन जिस तरह से मैं इसे चलाता हूं। सभी सुझावों का स्वागत है!

यदि आवश्यक हो तो मैंने नीचे अपना कोड सूचीबद्ध किया है।

from scrapy.spider import BaseSpider 
from scrapy.selector import HtmlXPathSelector 
from scrapy.item import Item, Field 
import re 

class Sale(Item): 
    Adresse = Field() 
    Pris = Field() 
    Salgsdato = Field() 
    SalgsType = Field() 
    KvmPris = Field() 
    Rum = Field() 
    Postnummer = Field() 
    Boligtype = Field() 
    Kvm = Field() 
    Bygget = Field() 

class HouseSpider(BaseSpider): 
    name = 'House' 
    allowed_domains = ["http://boliga.dk/"] 
    start_urls = ['http://www.boliga.dk/salg/resultater?so=1&type=Villa&type=Ejerlejlighed&type=R%%C3%%A6kkehus&kom=&amt=&fraPostnr=&tilPostnr=&iPostnr=&gade=&min=&max=&byggetMin=&byggetMax=&minRooms=&maxRooms=&minSize=&maxSize=&minsaledate=1992&maxsaledate=today&kode=&p=%d' %n for n in xrange(1, 23770, 1)] 

    def parse(self, response): 
     hxs = HtmlXPathSelector(response) 
     sites = hxs.select("id('searchresult')/tr") 
     items = []  
     for site in sites: 
      item = Sale() 
      item['Adresse'] = site.select("td[1]/a[1]/text()").extract() 
      item['Pris'] = site.select("td[2]/text()").extract() 
      item['Salgsdato'] = site.select("td[3]/text()").extract() 
      Temp = site.select("td[4]/text()").extract() 
      Temp = Temp[0] 
      m = re.search('\r\n\t\t\t\t\t(.+?)\r\n\t\t\t\t', Temp) 
      if m: 
       found = m.group(1) 
       item['SalgsType'] = found 
      else: 
       item['SalgsType'] = Temp 
      item['KvmPris'] = site.select("td[5]/text()").extract() 
      item['Rum'] = site.select("td[6]/text()").extract() 
      item['Postnummer'] = site.select("td[7]/text()").extract() 
      item['Boligtype'] = site.select("td[8]/text()").extract() 
      item['Kvm'] = site.select("td[9]/text()").extract() 
      item['Bygget'] = site.select("td[10]/text()").extract() 
      items.append(item) 
     return items 

धन्यवाद!

+1

पहली बात यह है कि आप इसके बारे में क्या कर सकते हैं, थ्रेड का उपयोग करना (मानक लाइब्रेरी दस्तावेज़ में प्रासंगिक इंफोस देखें), एक ही समय में 5/10 डाउनलोड चलाने के लिए, जो स्पष्ट रूप से एक बड़े निष्पादन समय में हो सकता है सुधार की। इसके अलावा, मुझे चीजों को तेज़ करने का कोई आसान तरीका नहीं दिखता है, क्योंकि आपका कोड सरल दिखता है। – michaelmeyer

+0

@doukremt: धन्यवाद! मैंने प्रलेखन को देखा है, और यह मुझे इसके लिए आवश्यक चीज़ों के लिए बहुत आसान लगता है। क्या यह सही ढंग से समझा जाता है कि प्रत्येक कनेक्शन के लिए, मुझे 'thread.start_new_thread (parse) 'कॉल करना चाहिए? या क्या मुझे सिर्फ 23770 पृष्ठों को स्क्रैप करने वाले दो कनेक्शन मिलेंगे? – Mace

+0

स्केपर वास्तव में async है, इसलिए यह वास्तव में समानांतर में डाउनलोड करता है (आप यह निर्धारित कर सकते हैं कि यह कितने समवर्ती अनुरोध करता है)। –

उत्तर

20

यहाँ कोशिश करने के लिए चीजों का एक संग्रह है:

  • उपयोग नवीनतम scrapy संस्करण (यदि पहले से ही प्रयोग नहीं)
  • जांच अमानक middlewares उपयोग किया जाता है, तो
  • कोशिश (CONCURRENT_REQUESTS_PER_DOMAIN, CONCURRENT_REQUESTS सेटिंग्स को बढ़ाने के लिए docs)
  • बारी बंद प्रवेश करने LOG_ENABLED = False (docs)
  • कोशिश yield के बजाय items सूची में आइटम एकत्र करने और उन्हें
  • उपयोग स्थानीय कैश डीएनएस लौटने का एक पाश में एक आइटम ing (this thread देखें)
  • जांच करता है, तो इस साइट डाउनलोड सीमा का उपयोग कर रहा है और अपने डाउनलोड गति को सीमित करता है (देखें this thread)
  • मकड़ी चलाने के दौरान
  • लॉग CPU और स्मृति उपयोग -
  • कोशिश scrapyd सेवा के तहत एक ही मकड़ी चलाने अगर वहाँ किसी भी समस्याओं हिस्सों को देख
  • देखें कि grequests + lxml में बेहतर प्रदर्शन करेगा (यदि आप को लागू करने के साथ किसी भी मदद की जरूरत है पूछना यह सोल संविधान)
  • pypy पर Scrapy चलाने की कोशिश करें, Running Scrapy on PyPy

आशा है कि मदद करता है देखते हैं।

+0

धन्यवाद! क्या प्रासंगिकता/प्रदर्शन सुधार के बाद अंक दिए गए हैं? – Mace

+0

खैर, यहां कोई विशेष आदेश नहीं है, लेकिन मैं पहले साइट डाउनलोड सीमा जैसी स्केपर समस्याओं से संबंधित नहीं हूं। – alecxe

+0

मैं इसे कैसे देखूं? मैंने धागे को देखा है, लेकिन मैं नहीं देख सकता कि यह कहां है कि यह जांचने के लिए कहां है? – Mace

5

अपना कोड देखकर, मैं कहूंगा कि उस समय का अधिकांश समय प्रतिक्रियाओं को संसाधित करने के बजाय नेटवर्क अनुरोधों में खर्च किया जाता है। @alecxe की सभी युक्तियां उनके उत्तर में लागू होती हैं, लेकिन मैं HTTPCACHE_ENABLED सेटिंग का सुझाव दूंगा, क्योंकि यह अनुरोधों को कैश करता है और इसे दूसरी बार करने से बचाता है। यह क्रॉल और यहां तक ​​कि ऑफ़लाइन विकास के बाद भी मदद करेगा। डॉक्स में अधिक जानकारी देखें: http://doc.scrapy.org/en/latest/topics/downloader-middleware.html#module-scrapy.contrib.downloadermiddleware.httpcache

+0

अच्छा बिंदु, धन्यवाद! – alecxe

+0

धन्यवाद, मैं कोशिश करूँगा। मैंने @alecxe के कई बिंदुओं का उल्लेख किया है। शुरुआत में स्क्रैपिंग बहुत तेज़ है, लेकिन फिर यह काफी धीमी हो जाती है, और मुझे स्क्रैप विफल हो जाते हैं, क्योंकि स्क्रैप 180 सेकंड से अधिक समय लेते हैं। निश्चित रूप से जानने के बिना, ऐसा लगता है कि मैं या तो पेज को बहुत मुश्किल से मार रहा हूं, या वे उत्तर की गति को कम करते हैं क्योंकि सभी अनुरोध एक ही आईपी से आते हैं। इस पर कोई विचार? – Mace

+0

@barraponto: 'TrueCACHE_ENABLED' को 'True' के बराबर' सेट करने में वास्तव में मदद मिली !! अब मेरी समस्या यह है कि मुझे वें "500 आंतरिक सर्वर त्रुटि" मिलती है। मैंने देरी का समय 5 सेकंड और 'CONCURRENT_REQUESTS_PER_DOMAIN = 2' पर सेट करने का प्रयास किया, लेकिन इससे मदद नहीं मिलती है। – Mace

0

मैं वेब समाप्त पर भी काम करते हैं, का उपयोग कर अनुकूलित सी #, और यह सीपीयू बाध्य समाप्त होता है, तो मैं सी का उपयोग करने जा रहा हूँ

पार्सिंग HTML सीपीयू डेटा कैश चल रही है, और बहुत यकीन है कि आपका सीपीयू एसएसई 4.2 का उपयोग नहीं कर रहा है, क्योंकि आप केवल सी/सी ++ का उपयोग करके इस सुविधा तक पहुंच सकते हैं।

यदि आप गणित करते हैं, तो आप जल्दी से गणना कर रहे हैं लेकिन स्मृति बाध्य नहीं हैं।

संबंधित मुद्दे