পাইথনের সাথে ওয়েব স্ক্র্যাপিং জাভাস্ক্রিপ্ট পৃষ্ঠা


178

আমি একটি সাধারণ ওয়েব স্ক্র্যাপার বিকাশের চেষ্টা করছি। আমি এইচটিএমএল কোড ছাড়াই পাঠ্য আহরণ করতে চাই। আসলে, আমি এই লক্ষ্যটি অর্জন করেছি, তবে আমি দেখেছি যে কয়েকটি পৃষ্ঠায় যেখানে জাভাস্ক্রিপ্ট লোড হয়েছে সেখানে আমি ভাল ফলাফল পাইনি।

উদাহরণস্বরূপ, কিছু জাভাস্ক্রিপ্ট কোড যদি কিছু পাঠ্য যোগ করে, আমি এটি দেখতে পাচ্ছি না, কারণ যখন আমি কল করি

response = urllib2.urlopen(request)

আমি যুক্ত হওয়া ব্যতীত মূল পাঠ্যটি পাই (কারণ জাভাস্ক্রিপ্ট ক্লায়েন্টে কার্যকর করা হয়)।

সুতরাং, আমি এই সমস্যাটি সমাধান করার জন্য কিছু ধারণা খুঁজছি।


2
মনে হচ্ছে আপনার আরও ভারী কিছু দরকার হতে পারে, সেলেনিয়াম বা ওয়াটারের চেষ্টা করুন।
উইম

2
আমি সফলভাবে (আমি কোবরা টুলকিট ব্যবহার করেছি জাভা এই কাজ করেছি lobobrowser.org/cobra.jsp ) আপনি পাইথন মধ্যে হ্যাক করতে চান যেহেতু (সবসময় একটি ভাল পছন্দ) আমি এই দুই অপশন সুপারিশ: - packtpub.com/article/ পাইথন-পার্ট -২-এর সাথে ওয়েব-স্ক্র্যাপিং - blog.databigbang.com/web-scraping-ajax-
এবং-

উত্তর:


203

সম্পাদনা 30 / ডিসেম্বর / 2017: এই উত্তরটি গুগল অনুসন্ধানগুলির শীর্ষ ফলাফলগুলিতে প্রদর্শিত হবে, তাই আমি এটি আপডেট করার সিদ্ধান্ত নিয়েছি। পুরানো উত্তরটি এখনও শেষ।

ড্রাইস্কেপ আর রক্ষণাবেক্ষণ করা হয় না এবং লাইব্রেরির ড্রিস্কেপ বিকাশকারীরা সুপারিশ করেন কেবল পাইথন 2। ফেনটম জেএসের সাথে সেলেনিয়ামের পাইথন লাইব্রেরিটি একটি ওয়েব ড্রাইভার হিসাবে যথেষ্ট দ্রুত এবং কাজটি করা সহজ হিসাবে ব্যবহার করে দেখতে পেয়েছি।

একবার আপনি ফ্যান্টম জেএস ইনস্টল করার পরে , 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
আমাদের মধ্যে যারা উইন্ডোজ প্রোগ্রামিং এর জন্য কোন বিকল্প?
হোশিকো 86

2
@Expenzorআমি উইন্ডোতে কাজ করছি। ফ্যান্টমজেএস ঠিকঠাক কাজ করে।
আকাশ চৌবে

17
মূল্যবান লক্ষণীয় ফ্যান্টমজেএস বন্ধ করে দেওয়া হয়েছে এবং ক্রোমের আলোতে এখন আর মাথা নিচু করে সমর্থন করা সক্রিয় বিকাশের অধীনে নেই। হেডলেস ক্রোম / ফায়ারফক্স ব্যবহারের পরামর্শ দেওয়া হচ্ছে।
23:48

3
এটি সেলেনিয়াম সমর্থন এবং ফ্যান্টমজেএস নিজেই। github.com/ariya/phantomjs/issues/15344
sytech

73

আমরা সঠিক ফলাফল পাচ্ছি না কারণ কোনও জাভাস্ক্রিপ্ট উত্পন্ন সামগ্রী ডমকে রেন্ডার করা দরকার। যখন আমরা একটি HTML পৃষ্ঠা আনয়ন করি, আমরা প্রাথমিক, জাভাস্ক্রিপ্ট, ডিওএম দ্বারা অরক্ষিত অবস্থায় আনয়ন করি।

সুতরাং পৃষ্ঠাটি ক্রল করার আগে আমাদের জাভাস্ক্রিপ্ট সামগ্রী রেন্ডার করতে হবে।

যেহেতু সেলেনিয়ামটি ইতিমধ্যে এই থ্রেডে বহুবার উল্লেখ করা হয়েছে (এবং এটি কখনও কখনও কতটা ধীর হয়ে যায় তাও উল্লেখ করা হয়েছিল), আমি আরও দুটি সম্ভাব্য সমাধানের তালিকা করব।


সমাধান 1: জাভাস্ক্রিপ্ট উত্পাদিত সামগ্রী ক্রল করতে স্ক্র্যাপি কীভাবে ব্যবহার করতে হয় সে সম্পর্কে এটি একটি খুব সুন্দর টিউটোরিয়াল এবং আমরা ঠিক সেগুলি অনুসরণ করতে চলেছি।

আমাদের যা প্রয়োজন হবে:

  1. আমাদের মেশিনে ডকার ইনস্টল। এটি এটি ওএস-ইন্ডিপেন্ডেন্ট প্ল্যাটফর্মটি ব্যবহার করার কারণে এটি এই মুহূর্ত পর্যন্ত অন্যান্য সমাধানগুলির চেয়ে বেশি plus

  2. আমাদের সম্পর্কিত ওএসের তালিকাভুক্ত নির্দেশাবলী অনুসরণ করে স্প্ল্যাশ ইনস্টল করুন
    স্প্ল্যাশ ডকুমেন্টেশন থেকে উদ্ধৃতি:

    স্প্ল্যাশ একটি জাভাস্ক্রিপ্ট রেন্ডারিং পরিষেবা। এটি একটি হালকা ওজনের একটি ওয়েব ব্রাউজার যা এইচটিটিপি এপিআই দিয়ে ট্যুইস্টেড এবং কিউটি 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 হওয়া উচিত: হোস্টের কাছ থেকে ডকারের ধারকটির আইপি ঠিকানা কীভাবে পাবেন? ):

    SPLASH_URL = 'http://localhost:8050'

    এবং অবশেষে আপনার এই মানগুলিও সেট করতে হবে:

    DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
    HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
  6. অবশেষে, আমরা একটি ব্যবহার করতে পারি SplashRequest:

    একটি সাধারণ মাকড়সাতে আপনার অনুরোধ অবজেক্ট থাকে যা আপনি ইউআরএল খোলার জন্য ব্যবহার করতে পারেন। আপনি যে পৃষ্ঠাটি খুলতে চান তাতে যদি জেএস উত্পাদিত ডেটা থাকে তবে পৃষ্ঠাটি রেন্ডার করতে আপনাকে স্প্ল্যাশআরকুয়েস্ট (বা স্প্ল্যাশফর্মআরকুয়েস্ট) ব্যবহার করতে হবে। এখানে একটি সাধারণ উদাহরণ:

    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

    স্প্ল্যাশ রেকুইস্টটি এইচটিএমএল হিসাবে ইউআরএলকে রেন্ডার করে এবং আপনি কলব্যাক (পার্স) পদ্ধতিতে ব্যবহার করতে পারেন এমন প্রতিক্রিয়া ফিরিয়ে দেয়।


সমাধান 2: আসুন এই মুহুর্তে এই পরীক্ষামূলকটিকে কল করুন (মে 2018) ...
সমাধানটি পাইথনের সংস্করণটি কেবলমাত্র 3.6 (এই মুহুর্তে) এর জন্য।

আপনি কি অনুরোধের মডিউলটি জানেন (ভাল কে না)?
এখন এটিতে একটি ওয়েব ক্রলিং করা ছোট ভাইবোন রয়েছে: অনুরোধ-এইচটিএমএল :

এই লাইব্রেরিটি পার্সিং এইচটিএমএলকে (যেমন ওয়েবকে স্ক্র্যাপিং) যতটা সম্ভব সহজ এবং স্বজ্ঞাত করতে ইচ্ছুক।

  1. অনুরোধ-এইচটিএমএল ইনস্টল করুন: 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পারি।


.reender () কে ফোন করার পরে, কীভাবে JS বিটগুলি বোঝাই করে পূর্ণ এইচটিএমএল সামগ্রী পাবেন সে সম্পর্কে আপনি কী প্রসারিত করতে পারেন? আমি এই বিন্দু পরে আটকে আছি। আমি r.html.htmlঅবজেক্টে জাভাস্ক্রিপ্ট থেকে সাধারণত পৃষ্ঠায় ইনজেক্ট করা সমস্ত আইফ্রেমগুলি দেখছি না ।
anon58192932

@ anon58192932 যেহেতু এই মুহুর্তে এটি একটি পরীক্ষামূলক সমাধান এবং ফলস্বরূপ আপনি ঠিক কী অর্জন করতে চাইছেন তা আমি জানি না, তাই আমি সত্যিই কিছু বলতে পারি না ... আপনি যদি না থাকেন তবে আপনি এখানে একটি নতুন প্রশ্ন তৈরি করতে পারেন
জন মিউটাফিস

2
আমি এই ত্রুটিটি পেয়েছি: রানটাইমআরার: বিদ্যমান ইভেন্ট লুপের মধ্যে এইচটিএমএল সেশন ব্যবহার করতে পারছি না। পরিবর্তে AsyncHTMLSession ব্যবহার করুন S
হাকআইট

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
এই ধরণের জিনিসটির জন্য সেলেনিয়াম সত্যই ভারী, এটি অকারণে ধীর হয়ে যেতে পারে এবং যদি আপনি ফ্যান্টমজেএস না ব্যবহার করেন তবে ব্রাউজারের মাথা প্রয়োজন, তবে এটি কার্যকর হবে।
জোশুয়া হেজেস

@ জোশুয়াহেজস আপনি হেডলেস মোডে আরও অন্যান্য স্ট্যান্ডার্ড ব্রাউজার চালাতে পারেন।
রেনল্ডসনল্প

22

আপনি যদি Requestsঅজগরটির জন্য মডিউলটি আগে কখনও ব্যবহার করেন তবে আমি সম্প্রতি জানতে পেরেছি যে বিকাশকারী একটি নতুন মডিউল নামে পরিচিতRequests-HTML যা এখন জাভাস্ক্রিপ্ট রেন্ডার করার ক্ষমতা রাখে।

আপনি এই মডিউলটি সম্পর্কে আরও জানতে https://html.python-requests.org/ দেখতে যেতে পারেন, বা যদি আপনার শুধুমাত্র জাভাস্ক্রিপ্ট রেন্ডারিং করতে আগ্রহী হন তবে আপনি https://html.python-requosts.org/?# জাভাস্ক্রিপ্ট দেখতে পারেন -support ব্যবহার করে জাভাস্ক্রিপ্ট রেন্ডার করতে মডিউলটি কীভাবে ব্যবহার করতে হয় তা সরাসরি শিখতে সহায়তা করুন।

মূলত, একবার আপনি 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.

আমি সম্প্রতি একটি ইউটিউব ভিডিও থেকে এটি সম্পর্কে জানতে পারি। এখানে ক্লিক করুন! ইউটিউব ভিডিও দেখতে যা মডিউলটি কীভাবে কাজ করে তা দেখায়।


3
লক্ষ্য করা উচিত যে এই মডিউলটির পাইথন ৩. for এর জন্য সমর্থন রয়েছে।
nat5142

1
আমি এই ত্রুটিটি পেয়েছি: এসএসএলআরআর: HTTPSConnicationPool (হোস্ট = 'docs.python-requests.org', পোর্ট = 443): ইউআরএল দিয়ে সর্বাধিক পুনরায় চেষ্টা করা হয়েছে: / (এসএসএলরারের কারণে হয়েছে (এসএসএলআরআর (1, '[SSL: TLSV1_ALERT_INTERNAL_ERROR] tlsv1 সতর্কতা অভ্যন্তরীণ ত্রুটি (_ssl.c: 1045) ')))
HuckIt

@ হকআইট অ্যাপলজিগুলি আমি সেই ত্রুটিটির সাথে পরিচিত নই, তবে ত্রুটিটি মনে হচ্ছে, আপনি যে ওয়েবসাইটটিতে পৌঁছানোর চেষ্টা করছেন সেটি একটি SSL শংসাপত্র সম্পর্কিত সমস্যা থাকতে পারে। দুঃখিত, এটি কোনও সমাধান নয়, তবে আমি আপনাকে একটি নতুন প্রশ্ন করার পরামর্শ দিচ্ছি, এখানে স্ট্যাক ওভারফ্লো (যদি এটি ইতিমধ্যে জিজ্ঞাসা করা না থাকে) এবং সম্ভবত আপনি যে ওয়েবসাইট url ব্যবহার করছিলেন এবং আপনার কোডের মতো আরও বিশদ দিন।
এসএসাহ

হুডের নীচে ক্রোমিয়াম ব্যবহার করা লাগে। যদিও আমার জন্য দুর্দান্ত কাজ করে
সিড

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 টি অনুসন্ধান করতে পারেন।


@ ক্রিস কেবল এতে যদি কেউ হোঁচট খায় এবং সেলেনিয়ামের মতো ভারী কিছু না করে এটি চেষ্টা করতে চান, তার একটি সংক্ষিপ্ত উদাহরণ এখানে। এটি ম্যাকমাস্টার-কার ওয়েবসাইটে একটি হেক্স বাদামের অংশ বিশদ পৃষ্ঠাটি খুলবে। তাদের ওয়েবসাইটের বিষয়বস্তু বেশিরভাগ জাভাস্ক্রিপ্ট ব্যবহার করে এনেছে এবং নেটিভ পৃষ্ঠাগুলির খুব কম তথ্য আছে। আপনি যদি আপনার ব্রাউজার বিকাশকারী সরঞ্জামগুলি খোলেন, নেটওয়ার্ক ট্যাবে নেভিগেট করুন এবং পৃষ্ঠাটি রিফ্রেশ করুন, আপনি পৃষ্ঠার দ্বারা তৈরি সমস্ত অনুরোধগুলি দেখতে পাবেন এবং প্রাসঙ্গিক ডেটা (এই ক্ষেত্রে অংশ বিশদ 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)

আসল যাদুটি মিডলওয়্যারস.পি-তে ঘটে। ডাউনলোডার মিডলওয়্যারের দুটি পদ্ধতি মুছে ফেলুন __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

সমগ্র জিনিস আমার GitHub পৃষ্ঠাতে হয় এবং আপনার কাছ থেকে এটি পেতে পারেন এখানে


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

আপনি পৃষ্ঠার বিভিন্ন অংশের জন্য কয়েকটি স্ক্রিপ্টে urlib, অনুরোধগুলি, বিউটিউশনসুপ এবং সেলেনিয়াম ওয়েব ড্রাইভারটি ব্যবহার করতে চাইবেন (কয়েকটি নাম লিখতে)।
কখনও কখনও আপনি এই মডিউলগুলির মধ্যে একটির সাথে আপনার যা প্রয়োজন তা পেয়ে যাবেন।
কখনও কখনও আপনার দুটি, তিন, বা এই সমস্ত মডিউলগুলির প্রয়োজন হবে।
কখনও কখনও আপনার ব্রাউজারে জেএস বন্ধ করতে হবে।
কখনও কখনও আপনার স্ক্রিপ্টে শিরোনামের তথ্য প্রয়োজন হয়।
কোনও ওয়েবসাইট একইভাবে স্ক্র্যাপ করা যায় না এবং কোনও ওয়েবসাইটকে আপনার ক্রলারটি সংশোধন না করে চিরকালের জন্য একইভাবে স্ক্র্যাপ করা যায় না, সাধারণত কয়েক মাস পরে। তবে এগুলি সবই ছিন্নমূল হতে পারে! যেখানে ইচ্ছা আছে সেখানে নিশ্চিত হওয়ার একটি উপায় আছে। কীভাবে এই মডিউলগুলি দিয়ে কী চেষ্টা করবেন এবং গুগলে আপনার ত্রুটিগুলি অনুলিপি এবং আটকানো কীভাবে সন্ধান করুন।
আপনার যদি ভবিষ্যতে অবিচ্ছিন্নভাবে স্ক্র্যাপড ডেটা প্রয়োজন হয় তবে আপনার যা কিছু প্রয়োজন তা কেবল স্ক্র্যাপ করুন এবং আচারের সাথে ডেট ফাইলগুলিতে এটি সঞ্চয় করুন।


3

পাইকিউটি 5 ব্যবহার করে

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

আমি এই প্রশ্নের উত্তর দু'দিন ধরে খোঁজার চেষ্টা করছি। অনেক উত্তর আপনাকে বিভিন্ন সমস্যার দিকে পরিচালিত করে। তবে উপরের সর্পটির উত্তরটি সত্যই সত্য। এটি সংক্ষিপ্ততম, সহজ সমাধান। কেবলমাত্র একটি শব্দ অনুসারে "ভার" শব্দটি ভেরিয়েবলের নাম উপস্থাপন করে , তাই এটি ব্যবহার করা উচিত:

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

এটি একটি পৃথক উত্তর নয়, সর্পের উত্তর সম্পর্কে মন্তব্য হওয়া উচিত।
Yserbius

1
এটা সুস্পষ্ট। তবে আমার কাছে এখনও অন্য 50 টি উত্তর নেই কারও উত্তরের বিষয়ে মন্তব্য করতে।
আব্দ_বিজিসি

0

আমার নিজের কিছু ওয়েব স্ক্র্যাপিং প্রকল্পগুলিতে আমাকে এই একই সমস্যাটি মোকাবেলা করতে হয়েছিল। আমি কীভাবে এর মোকাবিলা করেছি তা জেএস লোড না করে সরাসরি এপিআই-তে একটি http অনুরোধ করার জন্য পাইথন রিকুয়েস্টেস লাইব্রেরি ব্যবহার করে।

পাইথন অনুরোধ পাঠাগার এটির জন্য ভাল কাজ করে এবং আপনি HTTP অনুরোধগুলি পরিদর্শন উপাদানটি ব্যবহার করে এবং নেটওয়ার্ক ট্যাবে নেভিগেট করে দেখতে পারেন can

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.