रूबीलैंड में दो जेम्स पिछले कुछ वर्षों से वेब स्क्रैपिंग स्पॉटलाइट पर कब्जा कर चुके हैं: नोकोगिरी और मैकेनाइज। हम इन्हें एक व्यावहारिक उदाहरण के साथ कार्रवाई में लाने से पहले इनमें से प्रत्येक पर एक लेख खर्च करते हैं।
विषय
- वेब स्क्रैपिंग?
- अनुमति
- समस्या
- नोकोगिरी
- निष्कर्षण?
- पेजेज
- API
- नोड नेविगेशन
वेब स्क्रैपिंग?
वेब या स्क्रीन स्क्रैपिंग की तुलना में आसपास फैंसी शर्तें हैं। वेब हार्वेस्टिंग और वेब डेटा निष्कर्षण आपको तुरंत बता देते हैं कि क्या हो रहा है। हम वेब पेजेज से डेटा के निष्कर्षण को स्वचालित कर सकते हैं - और ये उतना जटिल भी नहीं है।
एक तरह से, ये टूल्स आपको मानव वेब ब्राउज़िंग की नकल और स्वचालन करने की अनुमति देते हैं। आप एक प्रोग्राम लिखते हैं जो केवल उस प्रकार के डेटा को निकालता है जो आपके लिए रुचिकर है। विशिष्ट डेटा को लक्षित करना CSS सेलेक्टर्स का उपयोग करने जितना आसान है।
कुछ साल पहले मैंने किसी ऑनलाइन वीडियो कोर्स की सदस्यता ली थी जिसमें दस लाख छोटे वीडियो थे लेकिन उन्हें बल्क में डाउनलोड करने का कोई विकल्प नहीं था। मुझे हर लिंक के माध्यम से अपने दम पर जाना पड़ा और डरावना 'सेव एज' खुद करना पड़ा। ये एक तरह का मानव वेब स्क्रैपिंग था - कुछ ऐसा जो हमें अक्सर करना पड़ता है जब हमारे पास उस तरह के सामान को स्वचालित करने का ज्ञान नहीं होता। कोर्स खुद ठीक था, लेकिन मैंने उसके बाद उनकी सेवाओं का उपयोग नहीं किया। ये सिर्फ बहुत थकाऊ था।
आज, मुझे ऐसी दिमाग पिघलाने वाली UX की ज्यादा परवाह नहीं होगी। एक स्क्रैपर जो मेरे लिए डाउनलोडिंग करेगा, उसे बनाने में मुझे केवल कुछ मिनट लगेंगे। कोई बड़ी बात नहीं!
आइए इसे शुरू करने से पहले वास्तविक रूप से जल्दी से तोड़ दें। पूरी चीज़ को कुछ चरणों में संघनित किया जा सकता है। पहले हम उस वेब पेज को लाते हैं जिसमें हमारे द्वारा आवश्यक वांछित डेटा होता है। फिर हम उस पेज के माध्यम से खोज करते हैं और उस जानकारी की पहचान करते हैं जिसे हम निकालना चाहते हैं।
अंतिम चरण इन बिट्स को लक्षित करना है, यदि आवश्यक हो तो उन्हें स्लाइस करें, और तय करें कि आप उन्हें कैसे और कहां स्टोर करना चाहते हैं। अच्छी तरह से लिखा गया HTML अक्सर इस प्रक्रिया को आसान और आनंददायक बनाने की कुंजी होता है। अधिक शामिल निष्कर्षण के लिए, अगर आपको खराब संरचित मार्कअप से निपटना पड़ता है तो ये दर्दनाक हो सकता है।
API के बारे में क्या? बहुत अच्छा सवाल। अगर आपके पास API के साथ किसी सर्विस तक पहुंच है, तो अक्सर अपने खुद के स्क्रैपर लिखने की बहुत कम आवश्यकता होती है। ये दृष्टिकोण ज्यादातर उन वेबसाइटों के लिए है जो उस तरह की सुविधा प्रदान नहीं करतीं। API के बिना, ये अक्सर वेबसाइटों से जानकारी के निष्कर्षण को स्वचालित करने का एकमात्र तरीका होता है।
आप पूछ सकते हैं, ये स्क्रैपिंग चीज़ वास्तव में कैसे काम करती है? गहरे अंत में कूदे बिना, संक्षिप्त उत्तर है, ट्री डेटा संरचनाओं को पार करके। नोकोगिरी आपके द्वारा इसे खिलाए गए दस्तावेजों से ये डेटा संरचनाएं बनाता है और आपको निष्कर्षण के लिए रुचि के बिट्स को लक्षित करने देता है। उदाहरण के लिए, CSS ट्री ट्रैवर्सल के लिए लिखी गई एक भाषा है, ट्री डेटा संरचनाओं की खोज के लिए, और हम डेटा निष्कर्षण के लिए इसका उपयोग कर सकते हैं।
वहां खेलने के लिए कई दृष्टिकोण और समाधान हैं। रूबीलैंड में दो जेम्स हैं जो कई वर्षों से स्पॉटलाइट पर कब्जा किए हुए हैं। बहुत से लोग अभी भी HTML स्क्रैपिंग आवश्यकताओं के लिए नोकोगिरी और मैकेनाइज पर भरोसा करते हैं। दोनों का परीक्षण किया गया है और उन्होंने खुद को उपयोग में आसान होने के साथ-साथ अत्यधिक सक्षम साबित किया है। हम दोनों को देखेंगे। लेकिन उससे पहले, मैं उस समस्या को संबोधित करने के लिए एक पल लेना चाहूंगा जिसे हम इस छोटी परिचयात्मक श्रृंखला के अंत में हल करने जा रहे हैं।
अनुमति
स्क्रैपिंग शुरू करने से पहले, सुनिश्चित करें कि जिन साइट्स को आप डेटा निष्कर्षण के लिए एक्सेस करने की कोशिश कर रहे हैं, उनकी अनुमति है। अगर साइट में API या RSS फीड है, उदाहरण के लिए, तो वांछित कंटेंट प्राप्त करना न केवल आसान हो सकता है, बल्कि यह पसंद का कानूनी विकल्प भी हो सकता है।
हर कोई इसकी सराहना नहीं करेगा अगर आप उनकी साइट्स पर बड़े पैमाने पर स्क्रैपिंग करते हैं - समझदारी से। उस विशेष साइट पर खुद को शिक्षित करें जिसमें आप रुचि रखते हैं, और खुद को मुसीबत में न डालें। संभावना कम है कि आप गंभीर नुकसान पहुंचाएंगे, लेकिन अनजाने में मुसीबत को जोखिम में डालना जाने का रास्ता नहीं है।
समस्या
मुझे एक नया पॉडकास्ट बनाने की आवश्यकता थी। डिज़ाइन वहां नहीं था जहां मैं चाहता था, और मुझे नई पोस्ट्स प्रकाशित करने का तरीका पसंद नहीं था। धिक्कार है WYSIWYGs! थोड़ा सा संदर्भ। लगभग दो साल पहले, मैंने अपने पॉडकास्ट का पहला संस्करण बनाया। विचार सिनात्रा के साथ खेलना और कुछ सुपर लाइटवेट बनाना था। मैं कुछ अप्रत्याशित मुद्दों में भाग गया क्योंकि मैंने बहुत कुछ दर्जी बनाया था।
रेल्स से आते हुए, ये निश्चित रूप से एक शैक्षिक यात्रा थी जिसकी मैं सराहना करता हूं, लेकिन मुझे जल्दी ही अफसोस हुआ कि मैंने एक स्टेटिक साइट का उपयोग नहीं किया जिसे मैं गिटहब के माध्यम से गिटहब पेजेज के जरिए डिप्लॉय कर सकता था। नए एपिसोड्स को डिप्लॉय करना और उन्हें बनाए रखना उस सरलता की कमी थी जिसकी मुझे तलाश थी। थोड़ी देर के लिए, मैंने फैसला किया कि मेरे पास तलने के लिए बड़ी मछलियां थीं और नए पॉडकास्ट सामग्री के उत्पादन पर ध्यान केंद्रित किया।
इस गर्मी में मैं गंभीर होने लगा और गिटहब पेजेज के माध्यम से होस्ट की गई एक मिडलमैन साइट पर काम किया। शो के दूसरे सीज़न के लिए, मैं कुछ नया चाहता था। एक नया, सरल डिज़ाइन, नए एपिसोड्स प्रकाशित करने के लिए मार्कडाउन, और हेरोकू के साथ कोई मुक्केबाजी नहीं - स्वर्ग! बात ये थी कि मेरे पास 139 एपिसोड्स पड़े थे जिन्हें पहले आयात और परिवर्तित करने की आवश्यकता थी ताकि वे मिडलमैन के साथ काम कर सकें।
पोस्ट्स के लिए, मिडलमैन .markdown फाइल्स का उपयोग करता है जिनमें तथाकथित फ्रंटमैटर होता है डेटा के लिए - जो मूल रूप से मेरा डेटाबेस बदल देता है। 139 एपिसोड्स के लिए इसे हाथ से करना कोई विकल्प नहीं है। ये वही है जो गणना के लिए है। मुझे अपने पुराने वेबसाइट के HTML को पार्स करने, प्रासंगिक कंटेंट को स्क्रैप करने, और इसे ब्लॉग पोस्ट्स में ट्रांसफर करने का एक तरीका निकालने की आवश्यकता थी जिनका उपयोग मैं मिडलमैन पर नए पॉडकास्ट एपिसोड्स प्रकाशित करने के लिए करता हूं।
इसलिए, अगले तीन लेखों में, मैं आपको रूबीलैंड में ऐसे कार्यों के लिए आमतौर पर उपयोग किए जाने वाले टूल्स से परिचित कराने जा रहा हूं। अंत में, हम कुछ व्यावहारिक दिखाने के लिए मेरे समाधान पर जाएंगे।
नोकोगिरी
यहां तक कि अगर आप रूबी/रेल्स के लिए पूरी तरह से नए हैं, तो संभावना बहुत अच्छी है कि आपने पहले से ही इस छोटे जेम के बारे में सुना है। नाम अक्सर गिराया जाता है और आसानी से आपके साथ चिपक जाता है। मुझे यकीन नहीं है कि कई लोग जानते हैं कि नोकोगिरी जापानी में "आरा" के लिए है।
एक बार जब आप समझ जाते हैं कि टूल क्या करता है तो ये एक उपयुक्त नाम है। इस जेम के निर्माता प्यारे टेंडरलव, आरोन पैटरसन हैं। नोकोगिरी XML और HTML दस्तावेजों को एक डेटा संरचना में परिवर्तित करता है - एक ट्री डेटा संरचना, अधिक सटीक होने के लिए। टूल तेज़ है और एक अच्छा इंटरफेस भी प्रदान करता है। कुल मिलाकर, ये एक बहुत शक्तिशाली लाइब्रेरी है जो आपकी HTML स्क्रैपिंग जरूरतों की एक भीड़ का ख्याल रखती है।
आप नोकोगिरी का उपयोग न केवल HTML पार्स करने के लिए कर सकते हैं; XML भी फेयर गेम है। ये आपको आपके द्वारा लोड किए गए दस्तावेजों को पार करने के लिए XML पथ भाषा और CSS दोनों इंटरफेस के विकल्प देता है। XML पथ भाषा, या संक्षेप में XPath, एक क्वेरी भाषा है।
ये हमें XML दस्तावेजों से नोड्स चुनने की अनुमति देता है। CSS सेलेक्टर्स शुरुआती लोगों के लिए अधिक परिचित होने की संभावना है। आपके द्वारा लिखी गई स्टाइल्स के साथ, CSS सेलेक्टर्स पेजेज के उन विशिष्ट वर्गों को लक्षित करना शानदार रूप से आसान बनाते हैं जो निष्कर्षण के लिए रुचिकर हैं। आपको बस नोकोगिरी को यह बताने की आवश्यकता है कि जब आप किसी विशेष गंतव्य को लक्षित करते हैं तो आप क्या चाहते हैं।
पेजेज
हमें हमेशा उस वास्तविक पेज को लाने के साथ शुरू करने की आवश्यकता होती है जिसमें हम रुचि रखते हैं। हम निर्दिष्ट करते हैं कि हम किस प्रकार का नोकोगिरी दस्तावेज़ पार्स करना चाहते हैं - उदाहरण के लिए XML या HTML:
Nokogiri::XML Nokogiri::HTML
some_scraper.rb
require "nokogiri"
require "open-uri"
page = Nokogiri::XML(File.open("some.xml"))
page = Nokogiri::HTML(File.open("some.html"))
Nokogiri:XML और Nokogiri:HTML IO ऑब्जेक्ट्स या स्ट्रिंग ऑब्जेक्ट्स ले सकते हैं। ऊपर जो होता है वह सीधा है। ये open-uri का उपयोग करके निर्दिष्ट पेज को खोलता और लाता है और फिर इसकी संरचना, इसके XML या HTML को एक नए नोकोगिरी दस्तावेज़ में लोड करता है। XML कुछ ऐसा नहीं है जिसे शुरुआती लोगों को बहुत बार निपटना पड़ता है।
इसलिए, मैं सलाह दूंगा कि हम अभी HTML पार्सिंग पर ध्यान केंद्रित करें। open-uri क्यों? रूबी स्टैंडर्ड लाइब्रेरी का ये मॉड्यूल हमें बिना ज्यादा झंझट के साइट को हथियाने देता है। क्योंकि IO ऑब्जेक्ट्स फेयर गेम हैं, हम open-uri का आसान उपयोग कर सकते हैं।
API
आइए इसे एक मिनी उदाहरण के साथ अभ्यास में लाएं:
at_css
some_podcast_scraper.rb
require 'nokogiri'
require "open-uri"
url = 'https://betweenscreens.fm/'
page = Nokogiri::HTML(open(url))
header = page.at_css("h2.post-title")
title = header.text
puts "This is the raw header of the latest episode: #{header}"
puts "This is the title of the latest episode: #{title}"
यहां हमने जो किया वह वेब स्क्रैपिंग में आमतौर पर शामिल सभी चरणों का प्रतिनिधित्व करता है - बस माइक्रो स्तर पर। हम तय करते हैं कि हमें किस URL की आवश्यकता है और किस साइट को लाने की आवश्यकता है, और हम उन्हें एक नए नोकोगिरी दस्तावेज़ में लोड करते हैं। फिर हम उस पेज को खोलते हैं और एक विशिष्ट खंड को लक्षित करते हैं।
यहां मैं केवल नवीनतम एपिसोड का शीर्षक जानना चाहता था। at_css मेथड और h2.post-title के लिए एक CSS सेलेक्टर का उपयोग करना निष्कर्षण बिंदु को लक्षित करने के लिए मुझे आवश्यक था। इस मेथड के साथ हम केवल इस विलक्षण तत्व को स्क्रैप करेंगे, हालांकि। ये हमें पूरा सेलेक्टर देता है - जो ज्यादातर समय ठीक वही नहीं है जो हमें चाहिए। इसलिए हम text मेथड के माध्यम से इस नोड के केवल आंतरिक टेक्स्ट भाग को निकालते हैं। तुलना के लिए, आप नीचे हेडर और टेक्स्ट दोनों के आउटपुट की जांच कर सकते हैं।
आउटपुट
This is the raw title of the latest episode: <h2 class="post-title"><a href="episodes/142/">David Heinemeier Hansson</a></h2> This is the title of the latest episode: David Heinemeier Hansson
हालांकि इस उदाहरण के बहुत सीमित अनुप्रयोग हैं, इसमें सभी सामग्रियां, सभी चरण हैं जिन्हें आपको समझने की आवश्यकता है। मुझे लगता है कि ये कितना सरल है ये अच्छा है। क्योंकि ये इस उदाहरण से स्पष्ट नहीं हो सकता, मैं यह इंगित करना चाहूंगा कि ये टूल कितना शक्तिशाली हो सकता है। आइए देखें कि हम नोकोगिरी स्क्रिप्ट के साथ और क्या कर सकते हैं।
ध्यान!
अदि आप एक शुरुआती हैं और इस बात को लेकर निश्चित नहीं हैं कि इसके लिए आवश्यक HTML को कैसे लक्षित किया जाए, तो मैं सलाह देता हूं कि आप अपने ब्राउज़र में वेबसाइटों की सामग्री का निरीक्षण कैसे करें, यह पता लगाने के लिए ऑनलाइन खोज करें। मूल रूप से, सभी प्रमुख ब्राउज़र इन दिनों इस प्रक्रिया को वास्तव में आसान बनाते हैं।
क्रोम पर आपको बस वेबसाइट पर एक एलिमेंट पर राइट-क्लिक करना होगा और इंस्पेक्ट विकल्प चुनना होगा। यह आपके ब्राउज़र के नीचे एक छोटी विंडो खोलेगा जो आपको साइट के DOM का एक प्रकार का एक्स-रे दिखाता है। इसके कई और विकल्प हैं, और मैं इस पर कुछ समय बिताने की सलाह दूंगा ताकि आप खुद को शिक्षित कर सकें। ये समय बुद्धिमानी से व्यतीत होता है!
css
css मेथड हमें न केवल पसंद का एक सिंगल एलिमेंट देगा बल्कि उस पेज पर खोज मानदंड से मेल खाने वाला कोई भी एलिमेंट देगा। बहुत साफ और सीधा!
some_scraper.rb
require 'nokogiri'
require "open-uri"
url = 'https://betweenscreens.fm/'
page = Nokogiri::HTML(open(url))
headers = page.css("h2.post-title")
headers.each do |header|
puts "This is the raw title of the latest episode: #{header}"
end
headers.each do |header|
puts "This is the title of the latest episode: #{header.text}"
end
आउटपुट
This is the raw title of the latest episode: <h2 class="post-title"><a href="episodes/142/">David Heinemeier Hansson</a></h2> This is the raw title of the latest episode: <h2 class="post-title"><a href="episodes/141/">Zach Holman</a></h2> This is the raw title of the latest episode: <h2 class="post-title"><a href="episodes/140/">Joel Glovier</a></h2> This is the raw title of the latest episode: <h2 class="post-title"><a href="episodes/139/">João Ferreira</a></h2> This is the raw title of the latest episode: <h2 class="post-title"><a href="episodes/138/">Corwin Harrell</a></h2> This is the raw title of the latest episode: <h2 class="post-title"><a href="episodes/137/">Roberto Machado</a></h2> This is the raw title of the latest episode: <h2 class="post-title"><a href="episodes/136/">James Edward Gray II</a></h2> This is the title of the latest episode: David Heinemeier Hansson This is the title of the latest episode: Zach Holman This is the title of the latest episode: Joel Glovier This is the title of the latest episode: João Ferreira This is the title of the latest episode: Corwin Harrell This is the title of the latest episode: Roberto Machado This is the title of the latest episode: James Edward Gray II
इस उदाहरण में एकमात्र छोटा अंतर यह है कि मैं पहले रॉ हेडर्स पर पुनरावृति करता हूं। मैंने text मेथड के साथ इसके आंतरिक टेक्स्ट को भी निकाला। नोकोगिरी स्वचालित रूप से पेज के अंत में रुक जाता है और स्वचालित रूप से कहीं भी पेजिनेशन का पालन करने का प्रयास नहीं करता।
मान लीजिए हम थोड़ी अधिक जानकारी चाहते हैं, कहते हैं प्रत्येक एपिसोड के लिए तारीख और उपशीर्षक। हम बस ऊपर के उदाहरण पर विस्तार कर सकते हैं। वैसे भी इस कदम को चरण-दर-चरण लेना एक अच्छा विचार है। एक छोटा सा टुकड़ा काम करवाएं और रास्ते में अधिक जटिलता जोड़ें।
some_scraper.rb
require 'nokogiri'
require "open-uri"
url = 'https://betweenscreens.fm/'
page = Nokogiri::HTML(open(url))
articles = page.css("article.index-article")
articles.each do |article|
header = article.at_css("h2.post-title")
date = article.at_css(".post-date")
subtitle = article.at_css(".topic-list")
puts "This is the raw header: #{header}"
puts "This is the raw date: #{date}"
puts "This is the raw subtitle: #{subtitle}\n\n"
puts "This is the text header: #{header.text}"
puts "This is the text date: #{date.text}"
puts "This is the text subtitle: #{subtitle.text}\n\n"
end
आउटपुट
This is the raw header: <h2 class="post-title"><a href="episodes/142/">David Heinemeier Hansson</a></h2> This is the raw date: <span class="post-date">Oct 18 | 2016</span> This is the raw subtitle: <h3 class="topic-list">Rails community | Tone | Technical disagreements | Community policing | Ungratefulness | No assholes allowed | Basecamp | Open source persona | Aspirations | Guarding motivations | Dealing with audiences | Pressure | Honesty | Diverse opinions | Small talk</h3> This is the text header: David Heinemeier Hansson This is the text date: Oct 18 | 2016 This is the text subtitle: Rails community | Tone | Technical disagreements | Community policing | Ungratefulness | No assholes allowed | Basecamp | Open source persona | Aspirations | Guarding motivations | Dealing with audiences | Pressure | Honesty | Diverse opinions | Small talk This is the raw header: <h2 class="post-title"><a href="episodes/141/">Zach Holman</a></h2> This is the raw date: <span class="post-date">Oct 12 | 2016</span> This is the raw subtitle: <h3 class="topic-list">Getting Fired | Taboo | Transparency | Different Perspectives | Timing | Growth Stages | Employment & Dating | Managers | At-will Employment | Tech Industry | Europe | Low hanging Fruits | Performance Improvement Plans | Meeting Goals | Surprise Firings | Firing Fast | Mistakes | Company Culture | Communication</h3> This is the text header: Zach Holman This is the text date: Oct 12 | 2016 This is the text subtitle: Getting Fired | Taboo | Transparency | Different Perspectives | Timing | Growth Stages | Employment & Dating | Managers | At-will Employment | Tech Industry | Europe | Low hanging Fruits | Performance Improvement Plans | Meeting Goals | Surprise Firings | Firing Fast | Mistakes | Company Culture | Communication This is the raw header: <h2 class="post-title"><a href="episodes/140/">Joel Glovier</a></h2> This is the raw date: <span class="post-date">Oct 10 | 2016</span> This is the raw subtitle: <h3 class="topic-list">Digital Product Design | Product Design @ GitHub | Loving Design | Order & Chaos | Drawing | Web Design | HospitalRun | Diversity | Startup Culture | Improving Lives | CURE International | Ember | Offline First | Hospital Information System | Designers & Open Source</h3> This is the text header: Joel Glovier This is the text date: Oct 10 | 2016 This is the text subtitle: Digital Product Design | Product Design @ GitHub | Loving Design | Order & Chaos | Drawing | Web Design | HospitalRun | Diversity | Startup Culture | Improving Lives | CURE International | Ember | Offline First | Hospital Information System | Designers & Open Source This is the raw header: <h2 class="post-title"><a href="episodes/139/">João Ferreira</a></h2> This is the raw date: <span class="post-date">Aug 26 | 2015</span> This is the raw subtitle: <h3 class="topic-list">Masters @ Work | Subvisual | Deadlines | Design personality | Design problems | Team | Pushing envelopes | Delightful experiences | Perfecting details | Company values</h3> This is the text header: João Ferreira This is the text date: Aug 26 | 2015 This is the text subtitle: Masters @ Work | Subvisual | Deadlines | Design personality | Design problems | Team | Pushing envelopes | Delightful experiences | Perfecting details | Company values This is the raw header: <h2 class="post-title"><a href="episodes/138/">Corwin Harrell</a></h2> This is the raw date: <span class="post-date">Aug 06 | 2015</span> This is the raw subtitle: <h3 class="topic-list">Q&A | 01 | University | Graphic design | Design setup | Sublime | Atom | thoughtbot | Working location | Collaboration & pairing | Vim advocates | Daily routine | Standups | Clients | Coffee walks | Investment Fridays |</h3> This is the text header: Corwin Harrell This is the text date: Aug 06 | 2015 This is the text subtitle: Q&A | 01 | University | Graphic design | Design setup | Sublime | Atom | thoughtbot | Working location | Collaboration & pairing | Vim advocates | Daily routine | Standups | Clients | Coffee walks | Investment Fridays | This is the raw header: <h2 class="post-title"><a href="episodes/137/">Roberto Machado</a></h2> This is the raw date: <span class="post-date">Aug 03 | 2015</span> This is the raw subtitle: <h3 class="topic-list">CEO @ Subvisual | RubyConf Portugal | Creators School | Consultancy | Company role models | Group Buddies | Portuguese startup | Rebranding | Technologies used | JS frameworks | TDD & BDD | Startup mistakes | Culture of learning | Young entrepreneurs</h3> This is the text header: Roberto Machado This is the text date: Aug 03 | 2015 This is the text subtitle: CEO @ Subvisual | RubyConf Portugal | Creators School | Consultancy | Company role models | Group Buddies | Portuguese startup | Rebranding | Technologies used | JS frameworks | TDD & BDD | Startup mistakes | Culture of learning | Young entrepreneurs This is the raw header: <h2 class="post-title"><a href="episodes/136/">James Edward Gray II</a></h2> This is the raw date: <span class="post-date">Jul 30 | 2015</span> This is the raw subtitle: <h3 class="topic-list">Screencasting | Less Code | Reading code | Getting unstuck | Rails’s codebase | CodeNewbie | Small examples | Future plans | PeepCode | Frequency & pricing</h3> This is the text header: James Edward Gray II This is the text date: Jul 30 | 2015 This is the text subtitle: Screencasting | Less Code | Reading code | Getting unstuck | Rails’s codebase | CodeNewbie | Small examples | Future plans | PeepCode | Frequency & pricing
इस बिंदु पर, हमारे पास पहले से ही खेलने के लिए कुछ डेटा है। हम इसे किसी भी तरह से संरक्षित या काट सकते हैं। उपरोक्त को केवल एक पठनीय तरीके से दिखाना चाहिए कि हमारे पास क्या है। बेशक हम text मेथड के साथ रेगुलर एक्सप्रेशन्स का उपयोग करके इनमें से प्रत्येक में गहराई से जा सकते हैं।
जब हम वास्तविक पॉडकास्ट समस्या को हल करने पहुंचेंगे तो हम इसे बहुत अधिक विस्तार से देखेंगे। ये regexp पर एक कक्षा नहीं होगी, लेकिन आप इसे और अधिक एक्शन में देखेंगे - लेकिन चिंता न करें, इतना नहीं कि आपका दिमाग खून बहाने लगे।
एट्रिब्यूट्स
इस स्तर पर जो काम आ सकता है वह व्यक्तिगत एपिसोड्स के लिए href निकालना भी है। ये इससे सरल नहीं हो सकता।
some_scraper.rb
require 'nokogiri'
require "open-uri"
url = 'https://betweenscreens.fm/'
page = Nokogiri::HTML(open(url))
articles = page.css("article.index-article")
articles.each do |article|
header = article.at_css("h2.post-title")
date = article.at_css(".post-date")
subtitle = article.at_css(".topic-list")
link = article.at_css("h2.post-title a")
podcast_url = "https://betweenscreens.fm/"
puts "This is the raw header: #{header}"
puts "This is the raw date: #{date}"
puts "This is the raw subtitle: #{subtitle}"
puts "This is the raw link: #{link}\n\n"
puts "This is the text header: #{header.text}"
puts "This is the text date: #{date.text}"
puts "This is the text subtitle: #{subtitle.text}"
puts "This is the raw link: #{podcast_url}#{link[:href]}\n\n"
end
यहां ध्यान देने योग्य सबसे महत्वपूर्ण बिट्स [:href] और podcast_url हैं। अगर आप [:] टैग करते हैं तो आप केवल लक्षित सेलेक्टर से एक एट्रिब्यूट निकाल सकते हैं। मैंने थोड़ा और अमूर्त किया, लेकिन आप नीचे अधिक स्पष्ट रूप से देख सकते हैं कि ये कैसे काम करता है।
... href = article.at_css("h2.post-title a")[:href] ...
प्रत्येक एपिसोड के लिए एक पूर्ण और उपयोगी URL प्राप्त करने के लिए, मैंने रूट डोमेन को एक वेरिएबल में सेव किया और प्रत्येक एपिसोड के लिए पूर्ण URL का निर्माण किया।
... podcast_url = "https://betweenscreens.fm/"
puts "This is the raw link: #{podcast_url}#{link[:href]}\n\n" ...
आइए आउटपुट पर एक त्वरित नज़र डालते हैं:
आउटपुट
This is the raw header: <h2 class="post-title"><a href="episodes/143/">Jason Long</a></h2> This is the raw date: <span class="post-date">Oct 25 | 2016</span> This is the raw subtitle: <h3 class="topic-list">Open source | Empathy | Lower barriers | Learning tool | Design contributions | Git website | Branding | GitHub | Neovim | Tmux | Design love | Knowing audiences | Showing work | Dribbble | Progressions | Ideas</h3> This is the raw link: <a href="episodes/143/">Jason Long</a> This is the text header: Jason Long This is the text date: Oct 25 | 2016 This is the text subtitle: Open source | Empathy | Lower barriers | Learning tool | Design contributions | Git website | Branding | GitHub | Neovim | Tmux | Design love | Knowing audiences | Showing work | Dribbble | Progressions | Ideas This is the href: https://betweenscreens.fm/episodes/143/ This is the raw header: <h2 class="post-title"><a href="episodes/142/">David Heinemeier Hansson</a></h2> This is the raw date: <span class="post-date">Oct 18 | 2016</span> This is the raw subtitle: <h3 class="topic-list">Rails community | Tone | Technical disagreements | Community policing | Ungratefulness | No assholes allowed | Basecamp | Open source persona | Aspirations | Guarding motivations | Dealing with audiences | Pressure | Honesty | Diverse opinions | Small talk</h3> This is the raw link: <a href="episodes/142/">David Heinemeier Hansson</a> This is the text header: David Heinemeier Hansson This is the text date: Oct 18 | 2016 This is the text subtitle: Rails community | Tone | Technical disagreements | Community policing | Ungratefulness | No assholes allowed | Basecamp | Open source persona | Aspirations | Guarding motivations | Dealing with audiences | Pressure | Honesty | Diverse opinions | Small talk This is the href: https://betweenscreens.fm/episodes/142/ This is the raw header: <h2 class="post-title"><a href="episodes/141/">Zach Holman</a></h2> This is the raw date: <span class="post-date">Oct 12 | 2016</span> This is the raw subtitle: <h3 class="topic-list">Getting Fired | Taboo | Transparency | Different Perspectives | Timing | Growth Stages | Employment & Dating | Managers | At-will Employment | Tech Industry | Europe | Low hanging Fruits | Performance Improvement Plans | Meeting Goals | Surprise Firings | Firing Fast | Mistakes | Company Culture | Communication</h3> This is the raw link: <a href="episodes/141/">Zach Holman</a> This is the text header: Zach Holman This is the text date: Oct 12 | 2016 This is the text subtitle: Getting Fired | Taboo | Transparency | Different Perspectives | Timing | Growth Stages | Employment & Dating | Managers | At-will Employment | Tech Industry | Europe | Low hanging Fruits | Performance Improvement Plans | Meeting Goals | Surprise Firings | Firing Fast | Mistakes | Company Culture | Communication This is the href: https://betweenscreens.fm/episodes/141/ This is the raw header: <h2 class="post-title"><a href="episodes/140/">Joel Glovier</a></h2> This is the raw date: <span class="post-date">Oct 10 | 2016</span> This is the raw subtitle: <h3 class="topic-list">Digital Product Design | Product Design @ GitHub | Loving Design | Order & Chaos | Drawing | Web Design | HospitalRun | Diversity | Startup Culture | Improving Lives | CURE International | Ember | Offline First | Hospital Information System | Designers & Open Source</h3> This is the raw link: <a href="episodes/140/">Joel Glovier</a> This is the text header: Joel Glovier This is the text date: Oct 10 | 2016 This is the text subtitle: Digital Product Design | Product Design @ GitHub | Loving Design | Order & Chaos | Drawing | Web Design | HospitalRun | Diversity | Startup Culture | Improving Lives | CURE International | Ember | Offline First | Hospital Information System | Designers & Open Source This is the href: https://betweenscreens.fm/episodes/140/ This is the raw header: <h2 class="post-title"><a href="episodes/139/">João Ferreira</a></h2> This is the raw date: <span class="post-date">Aug 26 | 2015</span> This is the raw subtitle: <h3 class="topic-list">Masters @ Work | Subvisual | Deadlines | Design personality | Design problems | Team | Pushing envelopes | Delightful experiences | Perfecting details | Company values</h3> This is the raw link: <a href="episodes/139/">João Ferreira</a> This is the text header: João Ferreira This is the text date: Aug 26 | 2015 This is the text subtitle: Masters @ Work | Subvisual | Deadlines | Design personality | Design problems | Team | Pushing envelopes | Delightful experiences | Perfecting details | Company values This is the href: https://betweenscreens.fm/episodes/139/ This is the raw header: <h2 class="post-title"><a href="episodes/138/">Corwin Harrell</a></h2> This is the raw date: <span class="post-date">Aug 06 | 2015</span> This is the raw subtitle: <h3 class="topic-list">Q&A | 01 | University | Graphic design | Design setup | Sublime | Atom | thoughtbot | Working location | Collaboration & pairing | Vim advocates | Daily routine | Standups | Clients | Coffee walks | Investment Fridays |</h3> This is the raw link: <a href="episodes/138/">Corwin Harrell</a> This is the text header: Corwin Harrell This is the text date: Aug 06 | 2015 This is the text subtitle: Q&A | 01 | University | Graphic design | Design setup | Sublime | Atom | thoughtbot | Working location | Collaboration & pairing | Vim advocates | Daily routine | Standups | Clients | Coffee walks | Investment Fridays | This is the href: https://betweenscreens.fm/episodes/138/ This is the raw header: <h2 class="post-title"><a href="episodes/137/">Roberto Machado</a></h2> This is the raw date: <span class="post-date">Aug 03 | 2015</span> This is the raw subtitle: <h3 class="topic-list">CEO @ Subvisual | RubyConf Portugal | Creators School | Consultancy | Company role models | Group Buddies | Portuguese startup | Rebranding | Technologies used | JS frameworks | TDD & BDD | Startup mistakes | Culture of learning | Young entrepreneurs</h3> This is the raw link: <a href="episodes/137/">Roberto Machado</a> This is the text header: Roberto Machado This is the text date: Aug 03 | 2015 This is the text subtitle: CEO @ Subvisual | RubyConf Portugal | Creators School | Consultancy | Company role models | Group Buddies | Portuguese startup | Rebranding | Technologies used | JS frameworks | TDD & BDD | Startup mistakes | Culture of learning | Young entrepreneurs This is the href: https://betweenscreens.fm/episodes/137/
साफ है, है ना? आप सेलेक्टर के [:class] को निकालने के लिए भी ऐसा ही कर सकते हैं।
require 'nokogiri'
require "open-uri"
url = 'https://betweenscreens.fm/'
page = Nokogiri::HTML(open(url))
body_classes = page.at_css("body")[:class]
अगर उस नोड में एक से अधिक क्लास हैं, तो आपको उन सभी की एक सूची मिलेगी।
नोड नेविगेशन
- parent
- children
- previous_sibling
- next_sibling
हम CSS या यहां तक कि jQuery में ट्री संरचनाओं से निपटने के आदी हैं। अगर नोकोगिरी ऐसी ट्रीज़ के भीतर घूमने के लिए एक आसान API प्रदान नहीं करता तो ये दर्दनाक होता।
some_scraper.rb
require 'nokogiri'
require "open-uri"
url = 'https://betweenscreens.fm/'
page = Nokogiri::HTML(open(url))
header = page.at_css("h2.post-title")
header_children = page.at_css("h2.post-title").children
header_parent = page.at_css("h2.post-title").parent
header_prev_sibling = page.at_css("h2.post-title").previous_sibling
puts "#{header}\n\n"
puts "#{header_children}\n\n"
puts "#{header_parent}\n\n"
puts "#{header_prev_sibling}\n\n"
आउटपुट
#header <h2 class="post-title"><a href="episodes/143/">Jason Long</a></h2> #header_children <a href="episodes/143/">Jason Long</a> #header_parent <article class="index-article"> <span class="post-date">Oct 25 | 2016</span><h2 class="post-title"><a href="episodes/143/">Jason Long</a></h2> <h3 class="topic-list">Open source | Empathy | Lower barriers | Learning tool | Design contributions | Git website | Branding | GitHub | Neovim | Tmux | Design love | Knowing audiences | Showing work | Dribbble | Progressions | Ideas</h3> <div class="soundcloud-player-small"> </div> </article> #header_previous_sibling <span class="post-date">Oct 25 | 2016</span>
जैसा कि आप खुद देख सकते हैं, ये कुछ बहुत शक्तिशाली सामान है - खासकर जब आप देखते हैं कि .parent एक ही बार में क्या इकट्ठा करने में सक्षम था। हाथ से एक गुच्छा नोड्स को परिभाषित करने के बजाय, आप उन्हें थोक में इकट्ठा कर सकते हैं।
आप अधिक जटिल ट्रैवर्सल के लिए उन्हें चेन भी कर सकते हैं। आप इसे जितना जटिल चाहें उतना ले सकते हैं, लेकिन मैं आपको चीजों को सरल रखने की सलाह दूंगा। ये जल्दी से थोड़ा अनियंत्रित और समझने में कठिन हो सकता है। याद रखें, "इसे सरल रखो, बेवकूफ!"
... header_parent_parent = page.at_css("h2.post-title").parent.parent
header_prev_sibling_parent_children = page.at_css("h2.post-title").previous_sibling.parent.children ...
some_scraper.rb
require 'nokogiri'
require "open-uri"
url = 'https://betweenscreens.fm/'
page = Nokogiri::HTML(open(url))
header = page.at_css("h2.post-title")
header_prev_sibling_children = page.at_css("h2.post-title").previous_sibling.children
header_parent_parent = page.at_css("h2.post-title").parent.parent
header_prev_sibling_parent = page.at_css("h2.post-title").previous_sibling.parent
header_prev_sibling_parent_children = page.at_css("h2.post-title").previous_sibling.parent.children
puts "#{header}\n\n"
puts "#{header_prev_sibling_children}\n\n"
puts "#{header_parent_parent}\n\n"
puts "#{header_prev_sibling_parent}\n\n"
puts "#{header_prev_sibling_parent_children}\n\n"
आउटपुट
#header <h2 class="post-title"><a href="episodes/143/">Jason Long</a></h2> #header_previous_sibling_children Oct 25 | 2016 #header_parent_parent <li> <article class="index-article"> <span class="post-date">Oct 25 | 2016</span><h2 class="post-title"><a href="episodes/143/">Jason Long</a></h2> <h3 class="topic-list">Open source | Empathy | Lower barriers | Learning tool | Design contributions | Git website | Branding | GitHub | Neovim | Tmux | Design love | Knowing audiences | Showing work | Dribbble | Progressions | Ideas</h3> <div class="soundcloud-player-small"> </div> </article> </li> #header_previous_sibling_parent <article class="index-article"> <span class="post-date">Oct 25 | 2016</span><h2 class="post-title"><a href="episodes/143/">Jason Long</a></h2> <h3 class="topic-list">Open source | Empathy | Lower barriers | Learning tool | Design contributions | Git website | Branding | GitHub | Neovim | Tmux | Design love | Knowing audiences | Showing work | Dribbble | Progressions | Ideas</h3> <div class="soundcloud-player-small"> </div> </article> #header_previous_sibling_parent_children <span class="post-date">Oct 25 | 2016</span><h2 class="post-title"><a href="episodes/143/">Jason Long</a></h2> <h3 class="topic-list">Open source | Empathy | Lower barriers | Learning tool | Design contributions | Git website | Branding | GitHub | Neovim | Tmux | Design love | Knowing audiences | Showing work | Dribbble | Progressions | Ideas</h3> <div class="soundcloud-player-small"> </div>
अंतिम विचार
नोकोगिरी एक विशाल लाइब्रेरी नहीं है, लेकिन इसमें देने के लिए बहुत कुछ है। मैं सलाह देता हूं कि आप जो सीखा है उसके साथ खेलें और जब आप दीवार से टकराएं तो इसके डॉक्यूमेंटेशन के माध्यम से अपने ज्ञान का विस्तार करें। लेकिन खुद को मुसीबत में न डालें!
यह छोटा परिचय आपको यह समझने के रास्ते पर अच्छी तरह से ले जाना चाहिए कि आप क्या कर सकते हैं और यह कैसे काम करता है। मुझे आशा है कि आप इसे अपने दम पर थोड़ा और एक्सप्लोर करेंगे और इसके साथ कुछ मज़ा करेंगे। जैसा कि आप अपने दम पर पता लगाएंगे, ये एक समृद्ध टूल है जो देता रहता है।