Integration von Spritzer in Schakerapi integrieren

In diesem Handbuch erfahren Sie, wie Sie Scraperapi problemlos in Splash integrieren können, um mit JavaScript-heftigen Websites umzugehen, die das Browser-Rendering erfordern. Ich werde Sie durch die empfohlenen Integrationsmethoden führen und Ihnen zeigen, wie Sie die Rendering -Funktionen von sowohl die Rendering -Funktionen und die Proxy -Infrastruktur von Scraperapi nutzen können.

Um das vollständige Rendering mit rotierenden Proxies von Scraperapi zu erzielen, laufen Sie einfach mit dem Proxy von Scraperapi konfiguriert.

Anforderungen

  • Python
  • Spritzer (über Docker)
  • requests (Python HTTP -Bibliothek)
  • Docker (zum Laufspritz)
  • Scraperapi & API -Schlüssel (speichern Sie dies in a .env Datei)

1. Installieren und Ausführen von Splash

Installieren Sie Ihre Anforderungen (requests ist der einzige, den Sie explizit installieren müssen pip). Wenn Docker nicht installiert ist, laden Sie es hier herunter und installieren Sie es hier. Stellen Sie nach der Installation sicher, dass es läuft, bevor Sie fortfahren.

Starten Sie Spritzer über Docker:

pip install requests
docker run -p 8050:8050 scrapinghub/splash

Wenn Sie einen Fehler erhalten, der besagt, dass Port 8050 bereits verwendet wird, bedeutet dies, dass ein weiterer Splash -Container bereits ausgeführt wird.

Um dies zu beheben:

  • Finden Sie den Container mit Port 8050
    Führen Sie dies in Ihrem Terminal aus:
  • Sie werden so etwas sehen wie:
CONTAINER ID   IMAGE                PORTS
abc123         scrapinghub/splash   0.0.0.0:8050->8050/tcp
  • Stoppen Sie den Container mit der Container -ID aus dem vorherigen Schritt:

Ersetzen abc123 Mit Ihrem tatsächlichen Container -ID und Ihren Splash -Container erneut ausführen.

2. Beispiel für Splash -Anfrage (Basic Integration)

Wenn Sie es noch nicht getan haben, erstellen Sie ein Konto auf Schakerapi und erhalten Sie Ihren API -Schlüssel.

Erstellen a .env Datei, um Ihren Schaferapi -Schlüssel sicher zu speichern:

SCRAPERAPI_KEY=your_scraperapi_key_here

Erstellen Sie in Ihrem Root -Ordner eine Python -Datei und fügen Sie Folgendes ein:

import os
import requests
from dotenv import load_dotenv
import time

# Load the ScraperAPI key from .env file
load_dotenv()
API_KEY = os.getenv("SCRAPERAPI_KEY")
SPLASH_EXECUTE_URL = "http://localhost:8050/execute"

# Optimized Lua script for ScraperAPI proxy
LUA_SCRIPT = """
function main(splash)
   splash.private_mode_enabled = false
   splash:on_request(function(request)
       request:set_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36')
       -- Set longer timeout for proxy connections
       request:set_timeout(45)
   end)

   -- Set page load timeout
   splash:set_viewport_size(1920, 1080)
   splash:set_viewport_full()
  
   local ok, reason = splash:go{
       splash.args.url,
       baseurl=splash.args.url,
       http_method="GET",
       headers={
           ("Accept") = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
           ("Accept-Language") = "en-US,en;q=0.5",
           ("Accept-Encoding") = "gzip, deflate",
           ("DNT") = "1",
           ("Connection") = "keep-alive",
           ("Upgrade-Insecure-Requests") = "1",
       }
   }
  
   if not ok then
       if reason:find("timeout") then
           return {error = "Page load timeout", reason = reason}
       else
           return {error = "Page load failed", reason = reason}
       end
   end
  
   -- Wait for JavaScript to load
   splash:wait(3)
  
   -- Check if page loaded successfully
   local title = splash:evaljs("document.title")
   if not title or title == "" then
       splash:wait(2)  -- Wait a bit more
   end
  
   return {
       html = splash:html(),
       title = splash:evaljs("document.title"),
       url = splash:url(),
       status = "success"
   }
end
"""

def scrape_with_splash_scraperapi(url, retries=3):
   proxy = f"http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001"
   print(f"🔍 Fetching with Splash + ScraperAPI: {url}")
  
   for attempt in range(retries):
       print(f"🔄 Attempt {attempt + 1}/{retries}")
      
       try:
           response = requests.post(SPLASH_EXECUTE_URL, json={
               "lua_source": LUA_SCRIPT,
               "url": url,
               "proxy": proxy,
               "timeout": 180,  # 3 minutes for Splash
               "resource_timeout": 60,  # 1 minute per resource
               "wait": 0.5,
               "html": 1,
               "har": 0,  # Disable HAR to reduce overhead
               "png": 0,  # Disable PNG to reduce overhead
           }, timeout=200)  # 200 seconds for the entire request
          
           if response.status_code == 200:
               try:
                   result = response.json()
                   if isinstance(result, dict) and "html" in result:
                       html_content = result("html")
                       if len(html_content) > 1000:
                           with open("output.html", "w", encoding="utf-8") as f:
                               f.write(html_content)
                           print(f"✅ Success! HTML saved to output.html")
                           print(f"📄 Page title: {result.get('title', 'N/A')}")
                           print(f"🔗 Final URL: {result.get('url', 'N/A')}")
                           return True
                       else:
                           print(f"⚠️ HTML content too short ({len(html_content)} chars)")
                   else:
                       # Fallback for plain HTML response
                       if len(response.text) > 1000:
                           with open("output.html", "w", encoding="utf-8") as f:
                               f.write(response.text)
                           print("✅ HTML saved to output.html (fallback)")
                           return True
               except:
                   # If JSON parsing fails, treat as plain HTML
                   if len(response.text) > 1000:
                       with open("output.html", "w", encoding="utf-8") as f:
                           f.write(response.text)
                       print("✅ HTML saved to output.html (plain text)")
                       return True
           else:
               print(f"❌ HTTP {response.status_code}")
               error_text = response.text(:500)
               print(f"Error: {error_text}")
              
               # Check for specific timeout errors
               if "timeout" in error_text.lower() or "504" in error_text:
                   print("⏰ Timeout detected, retrying with longer timeout...")
                   time.sleep(5)  # Wait before retry
                   continue
              
       except requests.exceptions.Timeout:
           print(f"⏰ Request timeout on attempt {attempt + 1}")
           if attempt < retries - 1:
               print("🔄 Retrying in 10 seconds...")
               time.sleep(10)
       except requests.exceptions.RequestException as e:
           print(f"🚨 Request failed: {e}")
           if attempt < retries - 1:
               print("🔄 Retrying in 5 seconds...")
               time.sleep(5)
  
   print("❌ All attempts failed")
   return False

def test_splash_connection():
   try:
       res = requests.get("http://localhost:8050", timeout=5)
       return res.status_code == 200
   except:
       return False

def test_scraperapi_key():
   if not API_KEY:
       print("❌ SCRAPERAPI_KEY not found in .env file")
       return False
   print(f"✅ ScraperAPI key loaded: {API_KEY(:8)}...")
   return True

if __name__ == "__main__":
   print("🚀 Starting Splash + ScraperAPI test...")
  
   if not test_scraperapi_key():
       exit(1)
  
   if not test_splash_connection():
       print("❌ Splash is not running. Start with:")
       print("docker run -p 8050:8050 scrapinghub/splash --max-timeout 300 --slots 5 --maxrss 4000")
       exit(1)
  
   print("✅ Splash is running")
  
   # Test with a simpler site first
   test_url = "http://quotes.toscrape.com/js"
   success = scrape_with_splash_scraperapi(test_url)
  
   if success:
       print("🎉 Test completed successfully!")
   else:
       print("💥 Test failed. Try restarting Splash with higher limits:")
       print("docker run -p 8050:8050 scrapinghub/splash --max-timeout 300 --slots 5 --maxrss 4000")

Dieses Skript sendet eine Anfrage zum Splash. Es geht durch den rotierenden Proxy von Scraperapi. Dies hilft, Blöcke zu umgehen und Inhalte zu laden, bei denen viel JavaScript verwendet wird. Anschließend speichert es die HTML lokal für die Inspektion und bestätigt, ob die Integration erfolgreich funktioniert.

Führen Sie Ihr Python -Skript aus, während Docker ausgeführt wird:

Screenshoot -CodeScreenshoot -Code

Dann öffnen Sie die Ausgabe:

Endgültige Ausgabevorschau

Screenshot -Zitate zum KratzenScreenshot -Zitate zum Kratzen

Alternative Methode: Proxy im Lua -Skript (nicht empfohlen)

Einige Entwickler können versuchen, den Stellvertreter direkt in das Lua -Skript zu injizieren:

splash:set_proxy('scraperapi:[email protected]:8001')

Diese Methode schlägt häufig bei Fehlern wie:

attempt to call method 'set_proxy' (a nil value)

Warum es fehlschlägt:

  • Einige Spritzbuilds unterstützen nicht set_proxy
  • Proxy -Befehle in Lua sind nicht so stabil
  • Das Debuggen von Lua -Stack -Spuren ist schwieriger als die Verwendung von Standard -Python -Fehlern

Häufige Herausforderungen

Hier sind einige Probleme, auf die Sie möglicherweise stoßen:

Problem Ursache Lösung
port is already allocated Docker -Hafenkonflikt auf 8050 Töten Sie den Prozess mithilfe lsof -i :8050 Und kill -9
set_proxy LUA -Fehler Ihr Splash -Build unterstützt nicht set_proxy Verwenden Sie das "proxy" Feld in der JSON -Anfrage anstatt es in Lua zu skriptieren
504 timeout Splash hat das Rendern innerhalb der Auszeit nicht fertiggestellt Erhöhen Sie die Zeitüberschreitung mit --max-timeout 300 Beim Ausführen des Docker -Containers
400 malformed request Fehlender oder falscher Schaferapierschlüssel Key in .env und laden Sie es mit dotenv in Ihrem Skript
urllib3 LibreSSL warning macOS wird mit Libressl anstelle von OpenSSL geliefert Verwenden pyenv Um Python mit OpenSSL 1.1+ zu installieren, um eine bessere Kompatibilität zu erhalten

Verwenden von Schaferfunktionen

Premium -Proxies & Geotargeting

Verwenden Sie spezielle Header, um das Verhalten des Schafschraitzers anzupassen:

Beispiel:

headers = {
   'X-ScraperAPI-Premium': 'true',
   'X-ScraperAPI-Country': 'us',
   'X-ScraperAPI-Session': '123'
}

response = requests.get(SPLASH_URL, params={
   'url': target_url,
   'wait': 1,
}, headers=headers, proxies={
   'http': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001',
   'https': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001',
})

Umgang mit Wiederholungen

Wiederholungslogik für fehlgeschlagene Anforderungen hinzufügen:

import time

def fetch_with_retry(url, max_retries=3):
   for attempt in range(max_retries):
       try:
           res = requests.get(SPLASH_URL, params={
               'url': url,
               'wait': 1,
           }, proxies={
               'http': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001',
               'https': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001',
           }, timeout=60)

           if res.status_code == 200:
               return res.text
       except Exception as e:
           print(f"Attempt {attempt+1} failed: {e}")
           time.sleep(2)
   return None

html = fetch_with_retry('http://quotes.toscrape.com/js')
print(html)

Gleichzeitig kratzen

Skalieren Sie mit mehreren Threads:

from concurrent.futures import ThreadPoolExecutor

API_KEY = 'YOUR_API_KEY'
SPLASH_URL = 'http://localhost:8050/render.html'

def scrape_page(url):
   response = requests.get(SPLASH_URL, params={
       'url': url,
       'wait': 1,
   }, proxies={
       'http': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001',
       'https': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001',
   }, timeout=60)
  
   return response.text if response.status_code == 200 else None

urls = (
   'http://quotes.toscrape.com/js/page/1/',
   'http://quotes.toscrape.com/js/page/2/',
   'http://quotes.toscrape.com/js/page/3/',
)

# Use max_workers equal to your ScraperAPI concurrent limit
with ThreadPoolExecutor(max_workers=5) as executor:
   results = list(executor.map(scrape_page, urls))

for i, html in enumerate(results):
   if html:
       print(f"Page {i+1}: {len(html)} characters")

Konfigurationstipps

Zeitüberschreitungseinstellungen

Stellen Sie die geeigneten Zeitüberschreitungen für die Verarbeitung von Schaferapi ein:

response = requests.get(SPLASH_URL, params={
   'url': target_url,
   'wait': 2,
   'timeout': 90,  # Allow time for ScraperAPI retries
}, proxies={
   'http': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001',
   'https': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001',
}, timeout=120)

Ressourcenfilterung

Die Leistung optimieren, indem Sie unnötige Ressourcen deaktivieren:

response = requests.get(SPLASH_URL, params={
   'url': target_url,
   'wait': 1,
   'images': 0,      # Disable images
   'filters': 'easylist',  # Block ads
}, proxies={
   'http': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001',
   'https': f'http://scraperapi:{API_KEY}@proxy-server.scraperapi.com:8001',
})

Letzte Notizen

  • Proxy -Routing durch Scraperapi ist die bevorzugte Methode. Es hält Splash stabil und funktional.
  • Vermeiden Sie Proxy -Logik in Lua -Skripten, um das Fehlerrisiko zu verringern.
  • Timeouts großzügig festlegen; Sowohl Splash als auch Scraperapi profitieren von> 90s.
  • API -Schlüssel speichern in .envniemals Hardcode.

Weitere Ressourcen:

Scraperapi -Dokumente

Splash Docs

Mein Name ist Kadek und ich bin ein Student aus Indonesien und studiere derzeit Informatik in Deutschland. Dieser Blog dient als Plattform, auf der ich mein Wissen zu Themen wie Web Scraping, Screen Scraping, Web Data Mining, Web Harvesting, Web Data Extraction und Web Data Parsing teilen kann.