पायथन के साथ वेब-स्क्रैपिंग जावास्क्रिप्ट पृष्ठ


178

मैं एक साधारण वेब स्क्रैपर विकसित करने की कोशिश कर रहा हूं। मैं HTML कोड के बिना पाठ निकालना चाहता हूं। वास्तव में, मैं इस लक्ष्य को प्राप्त करता हूं, लेकिन मैंने देखा है कि कुछ पृष्ठों में जहां जावास्क्रिप्ट लोड होता है, मुझे अच्छे परिणाम नहीं मिले।

उदाहरण के लिए, यदि कोई जावास्क्रिप्ट कोड कुछ पाठ जोड़ता है, तो मैं इसे नहीं देख सकता, क्योंकि जब मैं फोन करता हूं

response = urllib2.urlopen(request)

मुझे मूल पाठ को बिना जोड़े (क्योंकि जावास्क्रिप्ट क्लाइंट में निष्पादित किया गया है) मिलता है।

इसलिए, मैं इस समस्या को हल करने के लिए कुछ विचारों की तलाश कर रहा हूं।


2
लगता है कि आपको कुछ भारी पड़ सकता है, सेलेनियम या वतिर की कोशिश करें।
विम

2
मैंने इसे सफलतापूर्वक जावा में किया है (मैंने कोबरा टूलकिट lobobrowser.org/cobra.jsp का उपयोग किया है ) क्योंकि आप अजगर में हैक करना चाहते हैं (हमेशा एक अच्छा विकल्प) मैं इन दो विकल्पों की सलाह देता हूं: - packtpub.com/ficle/ web-scraping-with-python-part-2 - blog.databigbang.com/web-scraping-ajax-and-javascript-sites
bpgergo

जवाबों:


203

EDIT 30 / दिसंबर / 2017: यह उत्तर Google खोजों के शीर्ष परिणामों में प्रकट होता है, इसलिए मैंने इसे अपडेट करने का निर्णय लिया। पुराना जवाब अभी भी अंत में है।

ड्रायस्केप अब बनाए नहीं है और लाइब्रेरी ड्रायस्केप डेवलपर्स केवल पायथन 2 की सिफारिश करते हैं। मैंने फेलोम जेएस के साथ सेलेनियम की पाइथन लाइब्रेरी का उपयोग एक वेब चालक के रूप में तेजी से किया है और काम पूरा करने में आसान है।

एक बार जब आप प्रेत JS स्थापित कर लेते हैं , तो सुनिश्चित करें कि phantomjsबाइनरी वर्तमान पथ में उपलब्ध है:

phantomjs --version
# result:
2.1.1

उदाहरण

एक उदाहरण देने के लिए, मैंने HTML कोड के साथ एक नमूना पृष्ठ बनाया। ( लिंक ):

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Javascript scraping test</title>
</head>
<body>
  <p id='intro-text'>No javascript support</p>
  <script>
     document.getElementById('intro-text').innerHTML = 'Yay! Supports javascript';
  </script> 
</body>
</html>

जावास्क्रिप्ट के बिना यह कहता है: No javascript supportऔर जावास्क्रिप्ट के साथ:Yay! Supports javascript

जेएस समर्थन के बिना स्क्रैपिंग:

import requests
from bs4 import BeautifulSoup
response = requests.get(my_url)
soup = BeautifulSoup(response.text)
soup.find(id="intro-text")
# Result:
<p id="intro-text">No javascript support</p>

जेएस समर्थन के साथ स्क्रैपिंग:

from selenium import webdriver
driver = webdriver.PhantomJS()
driver.get(my_url)
p_element = driver.find_element_by_id(id_='intro-text')
print(p_element.text)
# result:
'Yay! Supports javascript'

आप जावास्क्रिप्ट संचालित वेबसाइटों को परिमार्जन करने के लिए पायथन लाइब्रेरी ड्रायस्क्रेप का उपयोग कर सकते हैं ।

जेएस समर्थन के साथ स्क्रैपिंग:

import dryscrape
from bs4 import BeautifulSoup
session = dryscrape.Session()
session.visit(my_url)
response = session.body()
soup = BeautifulSoup(response)
soup.find(id="intro-text")
# Result:
<p id="intro-text">Yay! Supports javascript</p>

16
अफसोस की बात है, कोई विंडोज सपोर्ट नहीं।
एक्सपेंसर

1
विंडोज के भीतर हम में से प्रोग्रामिंग के लिए कोई विकल्प?
होशिकोइरी

2
@Expenzorमैं खिड़कियों पर काम कर रहा हूं। PhantomJS ठीक काम करता है।
आकाश चौबे

17
वर्थ नोइंग फैंटमजस बंद कर दिया गया है और अब क्रोम के प्रकाश में सक्रिय विकास के तहत नहीं है जो अब बिना सिर के समर्थन में है। हेडलेस क्रोम / फायरफॉक्स का उपयोग करने का सुझाव दिया गया है।
sytech

3
यह स्वयं सेलेनियम समर्थन और फैंटमजस दोनों है। github.com/ariya/phantomjs/issues/15344
sytech

73

हमें सही परिणाम नहीं मिल रहे हैं क्योंकि किसी भी जावास्क्रिप्ट उत्पन्न सामग्री को DOM पर प्रस्तुत करना होगा। जब हम एक HTML पेज लाते हैं, तो हम जावास्क्रिप्ट, DOM द्वारा प्रारंभिक, अनमॉडिफाइड प्राप्त करते हैं।

इसलिए पेज को क्रॉल करने से पहले हमें जावास्क्रिप्ट सामग्री को प्रस्तुत करना होगा।

जैसा कि इस धागे में सेलेनियम का पहले से ही कई बार उल्लेख किया गया है (और कितनी धीमी गति से कभी-कभी इसका उल्लेख भी होता है), मैं दो अन्य संभावित समाधानों की सूची दूंगा।


समाधान 1: यह एक बहुत ही अच्छा ट्यूटोरियल है कि कैसे जावास्क्रिप्ट से क्रॉल की गई सामग्री को क्रॉल करने के लिए उपयोग किया जाए और हम उसी का पालन करने जा रहे हैं।

हमें क्या आवश्यकता होगी:

  1. हमारी मशीन में डॉकर स्थापित। यह इस बिंदु तक अन्य समाधानों के साथ एक प्लस है, क्योंकि यह एक ओएस-स्वतंत्र प्लेटफॉर्म का उपयोग करता है।

  2. हमारे संबंधित ओएस के लिए सूचीबद्ध अनुदेश के बाद स्पलैश स्थापित करें
    छप दस्तावेज से उद्धरण:

    स्पलैश एक जावास्क्रिप्ट प्रतिपादन सेवा है। यह एक HTTP एपीआई के साथ एक हल्का वेब ब्राउज़र है, जिसे ट्विस्टेड और क्यूटी 5 का उपयोग करके पायथन 3 में लागू किया गया है।

    अनिवार्य रूप से हम जावास्क्रिप्ट उत्पन्न सामग्री को रेंडर करने के लिए स्पलैश का उपयोग करने जा रहे हैं।

  3. स्प्लैश सर्वर चलाएँ sudo docker run -p 8050:8050 scrapinghub/splash:।

  4. स्क्रैप-स्प्लैश प्लगइन स्थापित करें :pip install scrapy-splash

  5. यह मानते हुए कि हमारे पास पहले से ही एक स्क्रैपी प्रोजेक्ट है (यदि नहीं, तो चलो एक बनाते हैं ), हम गाइड का पालन करेंगे और अपडेट करेंगे settings.py:

    फिर अपने स्क्रैपी प्रोजेक्ट पर जाएं settings.pyऔर इन बिचौलियों को सेट करें:

    DOWNLOADER_MIDDLEWARES = {
          'scrapy_splash.SplashCookiesMiddleware': 723,
          'scrapy_splash.SplashMiddleware': 725,
          'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
    }

    स्प्लैश सर्वर का URL (यदि आप Win या OSX का उपयोग कर रहे हैं तो यह docker मशीन का URL होना चाहिए: होस्ट से डॉकटर कंटेनर का IP पता कैसे प्राप्त करें? ):

    SPLASH_URL = 'http://localhost:8050'

    और अंत में आपको इन मूल्यों को भी निर्धारित करने की आवश्यकता है:

    DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
    HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
  6. अंत में, हम एक का उपयोग कर सकते हैं SplashRequest:

    एक सामान्य मकड़ी में आपके पास अनुरोध वस्तुएँ हैं जिनका उपयोग आप URL खोलने के लिए कर सकते हैं। यदि आप जिस पेज को खोलना चाहते हैं, उसमें जेएस जनरेट किया गया डेटा है, तो आपको पेज रेंडर करने के लिए SplashRequest (या SplashFormRequest) का उपयोग करना होगा। यहाँ एक सरल उदाहरण दिया गया है:

    class MySpider(scrapy.Spider):
        name = "jsscraper"
        start_urls = ["http://quotes.toscrape.com/js/"]
    
        def start_requests(self):
            for url in self.start_urls:
            yield SplashRequest(
                url=url, callback=self.parse, endpoint='render.html'
            )
    
        def parse(self, response):
            for q in response.css("div.quote"):
            quote = QuoteItem()
            quote["author"] = q.css(".author::text").extract_first()
            quote["quote"] = q.css(".text::text").extract_first()
            yield quote

    SplashRequest html के रूप में URL को प्रस्तुत करता है और उस प्रतिक्रिया को देता है जिसका उपयोग आप कॉलबैक (पार्स) विधि में कर सकते हैं।


समाधान 2: आइए इस प्रयोग को फिलहाल (मई 2018) कहते हैं ...
यह समाधान केवल पायथन के संस्करण 3.6 के लिए है (फिलहाल)।

क्या आप अनुरोध मॉड्यूल (अच्छी तरह से जो नहीं करता है) को जानते हैं ?
अब इसमें एक वेब क्रॉलिंग होती है, जो छोटा है: अनुरोध- HTML :

यह लाइब्रेरी संभव के रूप में सरल और सहज ज्ञान युक्त HTML (जैसे वेब को स्क्रैप करना) बनाने का इरादा रखती है।

  1. अनुरोध-html स्थापित करें: pipenv install requests-html

  2. पृष्ठ के url के लिए एक अनुरोध करें:

    from requests_html import HTMLSession
    
    session = HTMLSession()
    r = session.get(a_page_url)
  3. जावास्क्रिप्ट उत्पन्न बिट्स प्राप्त करने के लिए प्रतिक्रिया प्रस्तुत करें:

    r.html.render()

अंत में, मॉड्यूल स्क्रैपिंग क्षमताओं की पेशकश करने लगता है
वैकल्पिक रूप से, हम उस वस्तु के साथ सुंदरसुप का उपयोग करने के अच्छी तरह से प्रलेखित तरीके को आजमा सकते हैं, जो r.htmlहमने अभी प्रस्तुत किया है।


क्या आप .render () कॉल करने के बाद, JS बिट्स लोड करके, पूर्ण HTML सामग्री कैसे प्राप्त कर सकते हैं? मैं उस बिंदु के बाद फंस गया हूं। मैं उन सभी iframes को नहीं देख रहा हूँ जो सामान्य रूप से r.html.htmlऑब्जेक्ट में जावास्क्रिप्ट से पेज में इंजेक्ट किए जाते हैं ।
Anon58192932

@ anon58192932 इस समय से यह एक प्रायोगिक समाधान है और मुझे नहीं पता कि आप वास्तव में क्या परिणाम प्राप्त करने की कोशिश कर रहे हैं, मैं वास्तव में कुछ भी सुझा नहीं सकता ... आप एसओ पर यहां एक नया प्रश्न बना सकते हैं यदि आपने नहीं किया है एक समाधान अभी तक काम किया है
जॉन Moutafis

2
मुझे यह त्रुटि मिली: RuntimeError: किसी मौजूदा ईवेंट लूप के भीतर HTMLSession का उपयोग नहीं किया जा सकता है। इसके बजाय AsyncHTMLSession का उपयोग करें।
हुक इट

1
@ यह एक ज्ञात मुद्दा लगता है: github.com/psf/requests-html/issues/140
जॉन मुताफिस

47

शायद सेलेनियम यह कर सकता है।

from selenium import webdriver
import time

driver = webdriver.Firefox()
driver.get(url)
time.sleep(5)
htmlSource = driver.page_source

3
इस तरह की चीज़ के लिए सेलेनियम वास्तव में भारी है, जो अनावश्यक रूप से धीमा होगा और यदि आपको PhantomJS का उपयोग नहीं करना है, तो ब्राउज़र सिर की आवश्यकता होगी, लेकिन यह काम करेगा।
यहोशू

@JoshuaHedges आप हेडलेस मोड में अन्य अधिक मानक ब्राउज़र चला सकते हैं।
रेनॉल्डस्लैप

22

यदि आपने पहले कभी Requestsअजगर के लिए मॉड्यूल का उपयोग किया है , तो मुझे हाल ही में पता चला है कि डेवलपर ने एक नया मॉड्यूल बनाया है, Requests-HTMLजिसमें अब जावास्क्रिप्ट को प्रस्तुत करने की क्षमता भी है।

इस मॉड्यूल के बारे में अधिक जानने के लिए आप https://html.python-requests.org/ पर भी जा सकते हैं , या यदि आपका केवल जावास्क्रिप्ट प्रदान करने के बारे में दिलचस्पी है, तो आप https://html.python-requests.org/?#javascript पर जा सकते हैं समर्थन सीधे कैसे अजगर का उपयोग कर जावास्क्रिप्ट रेंडर करने के लिए मॉड्यूल का उपयोग करने के लिए सीखने के लिए।

अनिवार्य रूप से, एक बार जब आप Requests-HTMLमॉड्यूल को सही ढंग से स्थापित करते हैं , तो निम्न उदाहरण, जो उपरोक्त लिंक पर दिखाया गया है , दिखाता है कि आप इस मॉड्यूल का उपयोग किसी वेबसाइट को स्क्रैप करने और वेबसाइट के भीतर मौजूद जावास्क्रिप्ट को प्रस्तुत करने के लिए कैसे कर सकते हैं:

from requests_html import HTMLSession
session = HTMLSession()

r = session.get('http://python-requests.org/')

r.html.render()

r.html.search('Python 2 will retire in only {months} months!')['months']

'<time>25</time>' #This is the result.

मैंने हाल ही में इस बारे में एक YouTube वीडियो से सीखा है। यहाँ क्लिक करें! YouTube वीडियो देखने के लिए, जो प्रदर्शित करता है कि मॉड्यूल कैसे काम करता है।


3
ध्यान दें कि इस मॉड्यूल के पास केवल पायथन 3.6 के लिए समर्थन है।
nat5142 15

1
मुझे यह त्रुटि मिली: SSLError: HTTPSConnectionPool (host = 'docs.python-requests.org', port = 443): अधिकतम पुनर्प्राप्त url के साथ: आंतरिक त्रुटि (_ssl.c: 1045) ')))
HuckIt

@HuckIt आशंकाएँ मैं उस त्रुटि से परिचित नहीं हूँ, हालाँकि त्रुटि ऐसी लगती है, जिस वेबसाइट पर आप पहुँचने की कोशिश कर रहे थे, उसमें एसएसएल सर्टिफिकेशन से संबंधित समस्या हो सकती थी। क्षमा करें यह कोई समाधान नहीं है, लेकिन मैं आपको एक नया प्रश्न बनाने की सलाह दूंगा, यहां स्टैक ओवरफ्लो (यदि यह पहले से ही नहीं पूछा गया है) और संभवतः अधिक विवरण जैसे कि वेबसाइट का उपयोग कर रहे यूआरएल और अपना कोड दें।
18

हुड के नीचे क्रोमियम का उपयोग करने लगता है। हालांकि मेरे लिए बहुत अच्छा काम करता है
सिड

14

यह एक अच्छा समाधान भी लगता है, एक महान ब्लॉग पोस्ट से लिया गया है

import sys  
from PyQt4.QtGui import *  
from PyQt4.QtCore import *  
from PyQt4.QtWebKit import *  
from lxml import html 

#Take this class for granted.Just use result of rendering.
class Render(QWebPage):  
  def __init__(self, url):  
    self.app = QApplication(sys.argv)  
    QWebPage.__init__(self)  
    self.loadFinished.connect(self._loadFinished)  
    self.mainFrame().load(QUrl(url))  
    self.app.exec_()  

  def _loadFinished(self, result):  
    self.frame = self.mainFrame()  
    self.app.quit()  

url = 'http://pycoders.com/archive/'  
r = Render(url)  
result = r.frame.toHtml()
# This step is important.Converting QString to Ascii for lxml to process

# The following returns an lxml element tree
archive_links = html.fromstring(str(result.toAscii()))
print archive_links

# The following returns an array containing the URLs
raw_links = archive_links.xpath('//div[@class="campaign"]/a/@href')
print raw_links

12

ऐसा लगता है कि जिस डेटा की आप वास्तव में तलाश कर रहे हैं, उसे प्राथमिक पेज पर कुछ जावास्क्रिप्ट द्वारा बुलाए गए द्वितीयक URL के माध्यम से पहुँचा जा सकता है।

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


@ क्रिस बस अगर कोई इस पर ठोकर खाता है और इसे सेलेनियम के रूप में भारी के बजाय कुछ करने की कोशिश करना चाहता है, तो यहां एक छोटा उदाहरण है। यह मैकमास्टर-कार वेबसाइट पर हेक्स नट के लिए पार्ट डिटेल पेज खोलेगा। उनकी वेबसाइट सामग्री ज्यादातर जावास्क्रिप्ट का उपयोग करके प्राप्त की जाती है और इसमें बहुत कम मूल पृष्ठ की जानकारी होती है। यदि आप अपने ब्राउज़र डेवलपर टूल खोलते हैं, तो नेटवर्क टैब पर जाएं, और पृष्ठ को रीफ़्रेश करें, आप पृष्ठ द्वारा किए गए सभी अनुरोधों को देख सकते हैं और संबंधित डेटा (इस मामले में विस्तार से HTML) पा सकते हैं।
स्वीपिंगडोमन

यह फ़ायरफ़ॉक्स devtool नेटवर्क टैब में पाया जाने वाला एक अलग url है, जिसका यदि पालन किया जाता है, तो इसमें अधिकांश भाग जानकारी के लिए html होता है और आसान स्क्रैपिंग के लिए अन्य भाग की जानकारी को आसानी से नेविगेट करने के लिए आवश्यक कुछ मापदंडों को उजागर करता है। यह विशेष रूप से उदाहरण विशेष रूप से उपयोगी नहीं है क्योंकि मूल्य एक और जावास्क्रिप्ट फ़ंक्शन द्वारा उत्पन्न होता है, लेकिन स्टीफन की सलाह का पालन करने के इच्छुक किसी भी व्यक्ति के लिए एक परिचय के रूप में अच्छी तरह से सेवा करना चाहिए।
स्वीपिंगडोमन

12

जेएस और अजाक्स सामग्री को स्क्रैप करने के लिए सेलेनियम सबसे अच्छा है।

पायथन का उपयोग करके वेब से डेटा निकालने के लिए इस लेख की जाँच करें

$ pip install selenium

फिर क्रोम वेबड्राइवर डाउनलोड करें।

from selenium import webdriver

browser = webdriver.Chrome()

browser.get("https://www.python.org/")

nav = browser.find_element_by_id("mainnav")

print(nav.text)

आसान है, है ना?


8

आप वेबड्राइवर का उपयोग करके जावास्क्रिप्ट को भी निष्पादित कर सकते हैं।

from selenium import webdriver

driver = webdriver.Firefox()
driver.get(url)
driver.execute_script('document.title')

या एक चर में मूल्य की दुकान

result = driver.execute_script('var text = document.title ; return var')

या आप केवल driver.titleसंपत्ति का उपयोग कर सकते हैं
कोरी गोल्डबर्ग

8

मैं व्यक्तिगत रूप से स्क्रैपी और सेलेनियम का उपयोग करना पसंद करता हूं और दोनों अलग-अलग कंटेनरों में डॉकटरिंग करता हूं। इस तरह आप न्यूनतम परेशानी के साथ दोनों को स्थापित कर सकते हैं और आधुनिक वेबसाइटों को क्रॉल कर सकते हैं, जिनमें लगभग सभी एक या दूसरे रूप में जावास्क्रिप्ट होती हैं। यहाँ एक उदाहरण है:

scrapy startprojectअपना स्क्रैपर बनाने के लिए और अपने मकड़ी को लिखने के लिए उपयोग करें , कंकाल इस के रूप में सरल हो सकता है:

import scrapy


class MySpider(scrapy.Spider):
    name = 'my_spider'
    start_urls = ['https://somewhere.com']

    def start_requests(self):
        yield scrapy.Request(url=self.start_urls[0])


    def parse(self, response):

        # do stuff with results, scrape items etc.
        # now were just checking everything worked

        print(response.body)

असली जादू midwares.py में होता है। डाउनलोडर मिडलवेयर में दो तरीकों को अधिलेखित करें, __init__और process_request, निम्न तरीके से:

# import some additional modules that we need
import os
from copy import deepcopy
from time import sleep

from scrapy import signals
from scrapy.http import HtmlResponse
from selenium import webdriver

class SampleProjectDownloaderMiddleware(object):

def __init__(self):
    SELENIUM_LOCATION = os.environ.get('SELENIUM_LOCATION', 'NOT_HERE')
    SELENIUM_URL = f'http://{SELENIUM_LOCATION}:4444/wd/hub'
    chrome_options = webdriver.ChromeOptions()

    # chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
    self.driver = webdriver.Remote(command_executor=SELENIUM_URL,
                                   desired_capabilities=chrome_options.to_capabilities())


def process_request(self, request, spider):

    self.driver.get(request.url)

    # sleep a bit so the page has time to load
    # or monitor items on page to continue as soon as page ready
    sleep(4)

    # if you need to manipulate the page content like clicking and scrolling, you do it here
    # self.driver.find_element_by_css_selector('.my-class').click()

    # you only need the now properly and completely rendered html from your page to get results
    body = deepcopy(self.driver.page_source)

    # copy the current url in case of redirects
    url = deepcopy(self.driver.current_url)

    return HtmlResponse(url, body=body, encoding='utf-8', request=request)

सेटिंग्स में अगली पंक्तियों को खोलकर इस मिडलवेयर को सक्षम करना न भूलें:

DOWNLOADER_MIDDLEWARES = {
'sample_project.middlewares.SampleProjectDownloaderMiddleware': 543,}

डॉक्यूमेंटेशन के लिए अगला। अपनी Dockerfileएक हल्की छवि बनाएं (मैं यहां अजगर अल्पाइन का उपयोग कर रहा हूं), अपनी परियोजना निर्देशिका को कॉपी करें, आवश्यकताओं को स्थापित करें:

# Use an official Python runtime as a parent image
FROM python:3.6-alpine

# install some packages necessary to scrapy and then curl because it's  handy for debugging
RUN apk --update add linux-headers libffi-dev openssl-dev build-base libxslt-dev libxml2-dev curl python-dev

WORKDIR /my_scraper

ADD requirements.txt /my_scraper/

RUN pip install -r requirements.txt

ADD . /scrapers

और अंत में यह सब एक साथ लाएं docker-compose.yaml:

version: '2'
services:
  selenium:
    image: selenium/standalone-chrome
    ports:
      - "4444:4444"
    shm_size: 1G

  my_scraper:
    build: .
    depends_on:
      - "selenium"
    environment:
      - SELENIUM_LOCATION=samplecrawler_selenium_1
    volumes:
      - .:/my_scraper
    # use this command to keep the container running
    command: tail -f /dev/null

भागो docker-compose up -d। यदि आप ऐसा पहली बार कर रहे हैं तो लेटेस्ट सेलेनियम / स्टैंडअलोन-क्रोम लाने के लिए और आपकी स्क्रैपर इमेज बनाने में भी थोड़ा समय लगेगा।

एक बार यह हो जाने के बाद, आप जांच सकते हैं कि आपके कंटेनर किसके साथ चल रहे हैं docker psऔर यह भी जाँच लें कि सेलेनियम कंटेनर का नाम उस पर्यावरण चर से मेल खाता है जिसे हम अपने स्क्रैपर कंटेनर (यहाँ, यह था SELENIUM_LOCATION=samplecrawler_selenium_1) से गुजरे थे ।

docker exec -ti YOUR_CONTAINER_NAME shमेरे साथ अपने स्क्रैपर कंटेनर को दर्ज करें , मेरे लिए कमांड docker exec -ti samplecrawler_my_scraper_1 shसही निर्देशिका में सीडी थी और अपने स्क्रैपर को चलाएं scrapy crawl my_spider

पूरी बात मेरे जीथूब पेज पर है और आप इसे यहाँ से प्राप्त कर सकते हैं


5

ब्यूटीफुलसुप और सेलेनियम का मिश्रण मेरे लिए बहुत अच्छा काम करता है।

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup as bs

driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
    try:
        element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "myDynamicElement"))) #waits 10 seconds until element is located. Can have other wait conditions  such as visibility_of_element_located or text_to_be_present_in_element

        html = driver.page_source
        soup = bs(html, "lxml")
        dynamic_text = soup.find_all("p", {"class":"class_name"}) #or other attributes, optional
    else:
        print("Couldnt locate element")

पुनश्च आप यहां और अधिक प्रतीक्षा की स्थिति पा सकते हैं


4

आप पृष्ठ के विभिन्न भागों के लिए अपनी स्क्रिप्ट में urllib, अनुरोधों, beautifulSoup और सेलेनियम वेब ड्राइवर का उपयोग करना चाहते हैं, (कुछ नाम रखने के लिए)।
कभी-कभी आपको इन मॉड्यूलों में से केवल एक के साथ की आवश्यकता होती है।
कभी-कभी आपको दो, तीन या इन सभी मॉड्यूल की आवश्यकता होगी।
कभी-कभी आपको अपने ब्राउज़र पर js को बंद करना होगा।
कभी-कभी आपको अपनी स्क्रिप्ट में हेडर जानकारी की आवश्यकता होगी।
किसी भी वेबसाइट को उसी तरह से स्क्रैप नहीं किया जा सकता है और कोई भी वेबसाइट आपके क्रॉलर को संशोधित किए बिना हमेशा के लिए उसी तरह से स्क्रैप नहीं की जा सकती है, आमतौर पर कुछ महीनों के बाद। लेकिन वे सभी बिखरे हुए हो सकते हैं! जहाँ इच्छा है वहाँ यकीन के लिए एक रास्ता है।
यदि आपको भविष्य में लगातार स्क्रैप किए गए डेटा की आवश्यकता है, तो बस अपनी ज़रूरत की हर चीज़ को परिमार्जन करें और इसे .dat फ़ाइलों में अचार के साथ संग्रहीत करें।
बस खोज करते रहें कि इन मॉड्यूल के साथ क्या करने की कोशिश करें और Google में अपनी त्रुटियों को कॉपी और पेस्ट करें।


3

PyQt5 का उपयोग करना

from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEnginePage
import sys
import bs4 as bs
import urllib.request


class Client(QWebEnginePage):
    def __init__(self,url):
        global app
        self.app = QApplication(sys.argv)
        QWebEnginePage.__init__(self)
        self.html = ""
        self.loadFinished.connect(self.on_load_finished)
        self.load(QUrl(url))
        self.app.exec_()

    def on_load_finished(self):
        self.html = self.toHtml(self.Callable)
        print("Load Finished")

    def Callable(self,data):
        self.html = data
        self.app.quit()

# url = ""
# client_response = Client(url)
# print(client_response.html)

1

मैं दो दिनों से इस सवालों का जवाब खोजने की कोशिश कर रहा हूं। कई उत्तर आपको विभिन्न मुद्दों पर निर्देशित करते हैं। लेकिन ऊपर नागिन का जवाब वास्तव में बात है। यह सबसे छोटा, सरलतम उपाय है। बस अंतिम शब्द "var" एक अनुस्मारक है जो चर नाम का प्रतिनिधित्व करता है , इसलिए इसका उपयोग इस प्रकार किया जाना चाहिए:

 result = driver.execute_script('var text = document.title ; return text')

यह नागिन के जवाब पर टिप्पणी होनी चाहिए, अलग जवाब नहीं।
यसरबियस

1
ज़ाहिर सी बात है। लेकिन मेरे पास किसी और के जवाब पर टिप्पणी करने के लिए अभी तक 50 प्रतिनिधि नहीं हैं।
अब्द_बीजीसी

0

मुझे अपनी खुद की कुछ वेब स्क्रैपिंग परियोजनाओं पर इसी समस्या से निपटना पड़ा है। जेएस को लोड करने के बजाय, मैंने सीधे एपीआई के लिए एक HTTP अनुरोध करने के लिए अजगर अनुरोध पुस्तकालय का उपयोग करके इससे कैसे निपटा था।

अजगर अनुरोध पुस्तकालय इसके लिए अच्छी तरह से काम करता है, और आप नेटवर्क टैब का निरीक्षण और नेविगेट करके http अनुरोधों को देख सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.