2010-04-11 9 views
7

के दौरान URL संग्रहीत करना मैंने पाइथन में एक छोटा सा वेब स्पाइडर बनाया है जिसका उपयोग मैं URL एकत्र करने के लिए कर रहा हूं। मुझे सामग्री में रूचि नहीं है। अभी मैं सभी विज़िट किए गए यूआरएल को स्मृति में सेट में रख रहा हूं, क्योंकि मैं नहीं चाहता कि मेरा मकड़ी दो बार यूआरएल पर जाएं। बेशक यह इसे पूरा करने का एक बहुत ही सीमित तरीका है।स्पाइडरिंग

तो मेरे आने वाले यूआरएल का ट्रैक रखने का सबसे अच्छा तरीका क्या है?

क्या मुझे डेटाबेस का उपयोग करना चाहिए?

  • कौन सा एक? MySQL, SQLite, PostgreSQL?
  • मुझे URL कैसे सहेजना चाहिए? एक प्राथमिक कुंजी के रूप में जाने से पहले प्रत्येक यूआरएल डालने की कोशिश कर रहा है?

या मुझे उन्हें एक फ़ाइल में लिखना चाहिए?

  • एक फ़ाइल?
  • एकाधिक फाइलें? मुझे फ़ाइल-संरचना को कैसे डिजाइन करना चाहिए?

मुझे यकीन है कि इस या इसी तरह के विषयों पर किताबें और बहुत सारे कागजात हैं। क्या आप मुझे कुछ सलाह दे सकते हैं जो मुझे पढ़ना चाहिए?

+0

यह एक बहुत भारी कर्तव्य समस्या है, यह निर्भर करता है कि आप अपने समाधान को कितना भारी कर्तव्य चाहते हैं :) आप जिस बड़ी समस्या में भाग लेंगे वह ऐसी साइटें हैं जो कुकीज़ और यादृच्छिक संख्या को उनके यूआरएल में डालती हैं, जिससे अनंत क्रॉल स्पेस मिलता है कुछ बिंदु पर पकड़ा गया, आपको सामग्री के आधार पर डुप्लीकेट हटाने की आवश्यकता होगी। – Stephen

उत्तर

7

इन महत्वपूर्ण पहलुओं होने लगते हैं मेरे लिए:

  1. आप नहीं यूआरएल स्मृति में रख सकते हैं के रूप में राम बहुत अधिक
  2. आप तेजी से अस्तित्व लुकअप कम से कम ओ (logn) की जरूरत मिल जाएगा
  3. आप तेजी से सम्मिलन

ऐसा करने के कई तरीके हैं की जरूरत है और यह कितना बड़ा अपने डेटाबेस मिल जाएगा पर निर्भर करता है। मुझे लगता है कि एक एसक्यूएल डेटाबेस आपकी समस्या के लिए एक अच्छा मॉडल प्रदान कर सकता है।

शायद आपको केवल एक SQLite डेटाबेस चाहिए। आम तौर पर अस्तित्व जांच के लिए स्ट्रिंग लुकअप एक धीमी ऑपरेशन है। इसे तेज करने के लिए आप यूआरएल का सीआरसी हैश बना सकते हैं और अपने डेटाबेस में सीआरसी और यूआरएल दोनों स्टोर कर सकते हैं। आपके पास उस सीआरसी क्षेत्र पर एक सूचकांक होगा।

  • जब आप सम्मिलित करें: आप URL और हैश
  • डालने आप एक अस्तित्व देखने क्या करना चाहते हैं जब: आप संभावित नए URL का सीआरसी लेने के लिए और अगर यह पहले से ही अपने डेटाबेस में है की जाँच करें।

निश्चित रूप से यूआरएल हैश पर टकराव का मौका है, लेकिन यदि 100% स्पैनिंग आपके लिए महत्वपूर्ण नहीं है तो आप टकराव होने पर अपने डीबी में यूआरएल नहीं होने का हिट ले सकते हैं।

आप कई तरीकों से टकराव भी कम कर सकते हैं। उदाहरण के लिए आप अपने सीआरसी (सीआरसी 4 के बजाय सीआरसी 8) का आकार बढ़ा सकते हैं और एक बड़े आकार के साथ हैशिंग एल्गोरिदम का उपयोग कर सकते हैं। या सीआरसी के साथ ही यूआरएल लंबाई का उपयोग करें।

2

क्या आप अभी यूआरएल स्टोर कर रहे हैं? आपको mongoDB पर एक नज़र रखना चाहिए। यह एक नोएसक्यूएल डेटाबेस है जो कार्यान्वित करने में काफी आसान है।

http://try.mongodb.org/

यह अजगर बाइंडिंग भी मिला है:

http://api.mongodb.org/python/1.5.2%2B/index.html

1

चूंकि यह संभावना है कि आप इसी तरह बार (उदाहरण के लिए, जबकि एक वेबसाइट spidering, तो आप देखेंगे पर समान यूआरएल देखेंगे वेबसाइट के मुख्य पृष्ठ के बहुत सारे लिंक) मैं सलाह दूंगा कि आप यूआरएल को एक शब्दकोश में तब तक रखें जब तक आपकी याददाश्त सीमित न हो (केवल 10 एम यूआरएल या इसी तरह की उचित संख्या को हार्डकोड करें) और फिर जब यह बन जाए तो CDB database file पर शब्दकोश को फ्लश करें बहुत बड़ा।

इस तरह, आपके यूआरएल चेक का अधिकांश मेमोरी (जो तेज है) में होगा, जबकि स्मृति में नहीं हैं, फिर भी डिस्क से केवल 1-2 पढ़ने की आवश्यकता होगी ताकि आप यह देख सकें कि आपने उनका दौरा किया है।

4

यह उस स्पाइडरिंग के पैमाने पर निर्भर करता है जिसे आप करने जा रहे हैं, और जिस तरह की मशीन आप इसे कर रहे हैं। मान लीजिए कि एक सामान्य यूआरएल 60 बाइट्स की स्ट्रिंग है या तो, इन-मेमोरी सेट प्रति यूआरएल 100 बिट्स से थोड़ा अधिक ले जाएगा (पाइथन में सेट और डिक्ट्स को 60% पूर्ण होने की अनुमति नहीं है, गति कारणों से)। यदि आपके पास 64-बिट मशीन (और पायथन डिस्ट्रो) है, तो लगभग 16 जीबी रैम उपलब्ध है, तो आप निश्चित रूप से प्रश्न में महत्वपूर्ण सेट पर 10 जीबी से अधिक समर्पित कर सकते हैं, जिससे आप आसानी से 100 मिलियन यूआरएल या मकड़ी कर सकते हैं; लेकिन दूसरी चरम पर, यदि आपके पास 3 जीबी रैम वाली 32-बिट मशीन है, तो आप स्पष्ट रूप से एक महत्वपूर्ण जीबी से अधिक जीबी नहीं दे सकते हैं, जिससे आप लगभग 10 मिलियन यूआरएल तक सीमित हो सकते हैं। स्क्लाइट आकार की एक ही श्रृंखला के आसपास मदद करेगा जहां 32-बिट मशीन इसे नहीं बना सका लेकिन उदारता से संपन्न 64-बिट एक - 100 या 200 मिलियन यूआरएल कह सकता है।

उनसे परे, मैं पोस्टग्रेएसक्यूएल की सिफारिश करता हूं, जिसमें मूल रूप से कोई समस्या नहीं होने के कारण एक अलग मशीन (फास्ट लैन पर) चलाने में सक्षम होने का लाभ होता है, जिससे आप अपनी मुख्य मशीन को स्पाइडरिंग में समर्पित कर सकते हैं। मुझे लगता है कि MySQL & सी इसके लिए भी ठीक होगा, लेकिन मुझे PostgreSQL मानक अनुपालन और मजबूती से प्यार है ;-)। यह कुछ अरब समस्याओं के बिना कुछ अरब यूआरएल (बस एक तेज डिस्क, या एक बेहतर RAID व्यवस्था, और जितनी रैम आप कर सकते हैं उतनी रैम के रूप में, आप निश्चित रूप से चीजों को गति देने के लिए बर्दाश्त कर सकते हैं) की अनुमति देंगे।

URL हैं, जो काफी लंबा हो सकता है के एवज में एक निश्चित लंबाई हैश का उपयोग करके स्मृति/भंडारण को बचाने के लिए कोशिश कर रहा है ठीक है अगर आप एक सामयिक झूठी सकारात्मक है कि आप रेंगने क्या वास्तव में एक नया क्या है से बंद हो जाएगा के साथ ठीक कर रहे हैं यूआरएल। इस तरह के "टकराव" की संभावना बिल्कुल नहीं होनी चाहिए: भले ही आप केवल हैश के लिए 8 बाइट्स का उपयोग करते हैं, भले ही आप अरबों यूआरएल ("स्क्वायर रूट हेरिस्टिक" के लिए देख रहे हों तो आपको केवल कुछ टकराव का खतरा होना चाहिए जाने-माने समस्या)।

8-बाइट तार के साथ यूआरएल प्रतिनिधित्व करने के लिए, इन-स्मृति सेट वास्तुकला आसानी से एक अरब यूआरएल या अधिक एक अच्छी तरह से संपन्न मशीन पर ऊपर के रूप में उल्लिखित समर्थन करना चाहिए।

9

मैं मकड़ियों का एक बहुत लिखा है) -

तो, मोटे तौर पर कितने URLs आप मकड़ी के लिए चाहते हैं, और आप कितना रैम को छोड़ कर सकते हैं?। मेरे लिए, स्मृति से बाहर निकलने की तुलना में एक बड़ी समस्या यह है कि कोड या मशीन दुर्घटनाग्रस्त हो जाने पर आप सभी यूआरएल खोने की संभावना है या आप तय करते हैं कि आपको कोड को ट्विक करने की आवश्यकता है। यदि आप रैम से बाहर निकलते हैं तो अधिकांश मशीनें और ओएस इन दिनों पेज होंगे ताकि आप धीमे हो जाएंगे लेकिन फिर भी काम करेंगे। घंटे के घंटों और रन-टाइम के घंटों में इकट्ठे हुए यूआरएल के एक सेट को पुनर्निर्माण करना क्योंकि यह अब उपलब्ध नहीं है उत्पादकता के लिए एक वास्तविक झटका हो सकता है।

रैम में जानकारी रखने से आप खोना नहीं चाहते हैं। स्पष्ट रूप से एक डेटाबेस उस बिंदु पर जाने का तरीका है क्योंकि आपको यह देखने के लिए तेज़ी से यादृच्छिक पहुंच की आवश्यकता है कि क्या आपको पहले से ही एक यूआरएल मिला है या नहीं।बेशक इन-मेमोरी लुकअप तेज़ होते हैं लेकिन यह पता लगाने का व्यापार-बंद है कि मेमोरी में रखने के लिए कौन सी यूआरएल ओवरहेड जोड़ती है। यह निर्धारित करने के लिए कोड लिखने की कोशिश करने के बजाय कि मुझे कौन से यूआरएल की आवश्यकता है/जरूरत नहीं है, मैं इसे डेटाबेस में रखता हूं और अपना कोड साफ और रखरखाव करने और मेरे एसक्यूएल प्रश्नों और स्कीमा को समझने पर ध्यान केंद्रित करता हूं। अपने यूआरएल फ़ील्ड को एक अनन्य इंडेक्स बनाएं और डीबीएम स्वचालित रूप से अनावश्यक लिंक से परहेज करते समय उन्हें किसी भी समय नहीं ढूंढ पाएगा।

आपके द्वारा उपयोग किए जा रहे इंटरनेट और साइटों से आपका कनेक्शन शायद आपके आंतरिक नेटवर्क पर किसी मशीन पर डेटाबेस से आपके कनेक्शन से बहुत धीमा हो जाएगा। एक ही मशीन पर एक SQLite डेटाबेस सबसे तेज़ हो सकता है, हालांकि डीबीएम खुद पोस्टग्रेज़ के रूप में परिष्कृत नहीं है, जो मेरा पसंदीदा है। मैंने पाया कि एक ही मशीन पर डेटाबेस को एक ही स्विच पर डालने के रूप में मेरी स्पाइडरिंग मशीन बेहद तेज़ हो; एक मशीन को स्पिडरिंग, पार्सिंग, और फिर डेटाबेस को पढ़ना/लिखना बहुत गहन है, इसलिए यदि आपके पास पुराना बॉक्स लिनक्स फेंकता है, पोस्टग्रेस इंस्टॉल करता है, और शहर जाता है। यदि आपको अधिक गति की आवश्यकता है तो बॉक्स में कुछ अतिरिक्त रैम फेंको। डेटाबेस उपयोग के लिए उस अलग बॉक्स होने के बहुत अच्छा हो सकता है।

0

अब Pickling पर विचार करें: सरल संरचित भंडारण।

माइलेज निश्चित रूप से भिन्न होगा क्योंकि, जैसा कि अन्य उत्तरदाताओं ने कहा है, आप जल्दी से अपनी रैम समाप्त कर देंगे।