Ich habe eine Python-Funktion, die den Zeitplan einer Website durchsucht und in eine RDS-Datenbank hochlädt. Der Code funktioniert perfekt auf meinem lokalen Rechner (pyppeteer Version: 2.0.0, Python 3.12). Ich habe jedoch versucht, es auf AWS Lambda zu portieren, und mein Browser startet immer wieder nicht.
Ich habe die ausführbare Chromium-Datei DIESES Repositorys verwendet (aus /bin von npm i chrome-aws-lambda@~2.0.2 extrahiert und in einen S3-Bucket mit entsprechenden Berechtigungen hochgeladen), die dem entsprach pyppeteer-Version, die ich mit meiner Lambda-Funktion installiert habe (
). Der Python-Code lädt zunächst die Chromium-Instanz in das Verzeichnis /tmp herunter und versucht dann, den Browser von dort aus mit pyppeteer zu starten. Meine Lambda-Laufzeit hängt von Python 3.9 ab, da es sich um die neueste verfügbare Version handelt, die von „psycopg2._psycopg“ unterstützt wird. Außerdem glaube ich nicht, dass das das Problem ist.
Hat jemand eine Idee, warum mein Browser in meiner AWS Lambda-Laufzeit nicht gestartet werden kann? Ich denke, es könnte ein Problem mit meinen Argumenten für die Funktion launch() sein, aber ich bin mir nicht sicher, wohin ich von hier aus gehen soll.
Fehlerzeile:
Ich habe eine Python-Funktion, die den Zeitplan einer Website durchsucht und in eine RDS-Datenbank hochlädt. Der Code funktioniert perfekt auf meinem lokalen Rechner (pyppeteer Version: 2.0.0, Python 3.12). Ich habe jedoch versucht, es auf AWS Lambda zu portieren, und mein Browser startet immer wieder nicht. Ich habe die ausführbare Chromium-Datei DIESES Repositorys verwendet (aus /bin von npm i chrome-aws-lambda@~2.0.2 extrahiert und in einen S3-Bucket mit entsprechenden Berechtigungen hochgeladen), die dem entsprach pyppeteer-Version, die ich mit meiner Lambda-Funktion installiert habe ([code]pip3 install pyppeteer -t .[/code]). Der Python-Code lädt zunächst die Chromium-Instanz in das Verzeichnis /tmp herunter und versucht dann, den Browser von dort aus mit pyppeteer zu starten. Meine Lambda-Laufzeit hängt von Python 3.9 ab, da es sich um die neueste verfügbare Version handelt, die von „psycopg2._psycopg“ unterstützt wird. Außerdem glaube ich nicht, dass das das Problem ist. Hat jemand eine Idee, warum mein Browser in meiner AWS Lambda-Laufzeit nicht gestartet werden kann? Ich denke, es könnte ein Problem mit meinen Argumenten für die Funktion launch() sein, aber ich bin mir nicht sicher, wohin ich von hier aus gehen soll. Fehlerzeile: [code]browser = await launch( headless=True, args=[ '--no-sandbox', '--disable-setuid-sandbox', '--disable-gpu', "--single-process", "--disable-dev-shm-usage", "--no-zygote", ], executablePath="/tmp/headless-chromium", userDataDir="/tmp", ) [/code] Fehler in der Lambda-Konsole: [code]Status: Failed Test Event Name: testEvent
Response: { "errorMessage": "Browser closed unexpectedly:\n", "errorType": "BrowserError", "requestId": "a6a20222-6082-4618-b388-fbd4c88bda7d", "stackTrace": [ " File \"/var/task/lambda_function.py\", line 369, in lambda_handler\n shows = asyncio.run(scrape_all_schedules())\n", " File \"/var/lang/lib/python3.9/asyncio/runners.py\", line 44, in run\n return loop.run_until_complete(main)\n", " File \"/var/lang/lib/python3.9/asyncio/base_events.py\", line 647, in run_until_complete\n return future.result()\n", " File \"/var/task/lambda_function.py\", line 225, in scrape_all_schedules\n browser = await launch(\n", " File \"/var/task/pyppeteer/launcher.py\", line 307, in launch\n return await Launcher(options, **kwargs).launch()\n", " File \"/var/task/pyppeteer/launcher.py\", line 168, in launch\n self.browserWSEndpoint = get_ws_endpoint(self.url)\n", " File \"/var/task/pyppeteer/launcher.py\", line 227, in get_ws_endpoint\n raise BrowserError('Browser closed unexpectedly:\\n')\n" ] }
Function Logs: Request ID: a6a20222-6082-4618-b388-fbd4c88bda7d [/code] VOLLSTÄNDIGER CODE: [code]import asyncio from datetime import datetime from pyppeteer import launch import os import psycopg2 import boto3
try: print(f"Downloading Chromium binary from s3://{bucket_name}/{object_key} to {chromium_path}") s3_client.download_file(bucket_name, object_key, chromium_path) os.chmod('/tmp/headless-chromium', 0o755) print("Chromium binary downloaded successfully.") except Exception as e: print(f"Error downloading Chromium: {e}") raise e # Re-raise the exception to halt the function if download fails
async def close_browser(browser): for page in await browser.pages(): await page.close() await browser.close()
def fallback_to_pkill(): try: print("Executing pkill to terminate Chrome...") os.system("pkill -f chrome") print("Chrome processes terminated with pkill.") except Exception as e: print(f"Error while executing pkill: {e}")
async def scrape_showSite(browser, show_url): if not show_url: return "Unknown", False
# Wait for the DJ name element to load await page.waitForSelector('.dj-name', {'timeout': 10000}) dj_name = await page.evaluate('''() => { const djElement = document.querySelector('.dj-name'); if (!djElement) return "Unknown";
# Check the first element in the with class "timeslot show-schedule" alternates = await page.evaluate('''() => { const timeslotUl = document.querySelector('ul.timeslot.show-schedule'); if (!timeslotUl) return false;
const firstLi = timeslotUl.querySelector('li'); if (!firstLi) return false;
const text = firstLi.innerText || ""; return text.includes("Every other week") ? true : false; }''')
return dj_name or "Unknown", alternates
except Exception as e: print(f"Error scraping DJ name for URL {show_url}: {e}") return "Unknown", False
finally: await page.close()
async def scrape_schedule(page, todays_date): print("Scraping schedule...") try: await page.waitForFunction( '''() => document.querySelectorAll('a[href^="https://spinitron.com/KDVS/show/"]').length >= 225''', {'timeout': 10000} ) except asyncio.TimeoutError: print("Timeout occurred while waiting for the schedule to load. Attempting to scrape remaining tags.")
chromium_path = '/tmp/headless-chromium' if os.path.exists(chromium_path): print("Chromium binary found. Launching browser...") else: print(f"Error: Chromium binary not found at {chromium_path}")
for show in shows: existing = next((s for s in all_shows if s['showName'] == show['showName'] and s['startTime'] == show['startTime'] and s['endTime'] == show['endTime']), None) if existing: existing['dates'].append(show['date']) else: all_shows.append({ 'showName': show['showName'], 'startTime': show['startTime'], 'endTime': show['endTime'], 'dates': [show['date']], 'image_url': show['image_url'], 'current_dotw': show['current_dotw'], 'show_url': show['show_url'] })
for week in range(9): print(f"Processing week {week + 1}...") await page.waitForSelector(NEXT_WEEK_BUTTON_SELECTOR, {'timeout': 10000, 'visible': True}) print("Found Selector: clicking...") await page.evaluate(f'document.querySelector("{NEXT_WEEK_BUTTON_SELECTOR}").click()') print("Clicked and waiting for schedule to load...")
for show in next_week_shows: existing = next((s for s in all_shows if s['showName'] == show['showName'] and s['startTime'] == show['startTime'] and s['endTime'] == show['endTime']), None) if existing: existing['dates'].append(show['date']) else: all_shows.append({ 'showName': show['showName'], 'startTime': show['startTime'], 'endTime': show['endTime'], 'dates': [show['date']], 'image_url': show['image_url'], 'current_dotw': show['current_dotw'], 'show_url': show['show_url'] })
# Scrape DJ names+alternates for each show for show in all_shows: if show['show_url']: show['dj_name'], show['alternates'] = await scrape_showSite(browser, show['show_url'])
except Exception as e: print(f"Error during scraping: {e}")
finally: print("Shutting down...") try: await asyncio.wait_for(close_browser(browser), timeout=5) print("Browser closed successfully.") except asyncio.TimeoutError: print("Graceful shutdown timed out. Falling back to pkill...") fallback_to_pkill() except Exception as e: print(f"Unexpected error during shutdown: {e}") print("Falling back to pkill...") fallback_to_pkill()
return all_shows
def save_to_database(shows): try: print("Connecting to the database...") conn = psycopg2.connect( host=os.getenv("DB_HOST"), port=os.getenv("DB_PORT"), database=os.getenv("DB_NAME"), user=os.getenv("DB_USER"), password=os.getenv("DB_PASSWORD") ) print("Connected successfully!")
cursor = conn.cursor()
cursor.execute("DROP TABLE IF EXISTS temp_shows;") cursor.execute(""" CREATE TABLE temp_shows (LIKE shows INCLUDING ALL); """)
for show in shows: formatted_dates = '{' + ','.join([f'"{date}"' for date in show['dates']]) + '}' cursor.execute( """ INSERT INTO temp_shows (name, dj_name, start_time, end_time, show_dates, playlist_image_url, current_dotw, alternates) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) """, ( show['showName'], show['dj_name'], show['startTime'], show['endTime'], formatted_dates, show['image_url'], show['current_dotw'], show['alternates'] ) )
conn.commit() print("Database updated successfully!") except Exception as e: print(f"Error saving to database: {e}") if conn: conn.rollback() finally: if 'conn' in locals() and conn: conn.close()
Ich arbeite an AWS Lambda im Spring Boot-Framework.
Ich habe den Code aus dem folgenden Link verwendet, um Zertifikate aus Dateien zu laden, weil beim Erstellen des PKIX-Pfads ein Fehler aufgetreten...
Ich arbeite an AWS Lambda im Spring Boot-Framework.
Ich habe den Code aus dem folgenden Link verwendet, um Zertifikate aus Dateien zu laden, weil beim Erstellen des PKIX-Pfads ein Fehler aufgetreten...
Wenn ich XAMPP öffne und auf die Schaltfläche „MySQL starten“ klicke, erhalte ich eine Fehlermeldung. Ich hatte es kurz zuvor gestartet, aber jetzt funktioniert es nicht mehr.
Es wurde unten in xammp...
Ich versuche, ein kostenloses SMTP-Relay von SendGrid zum Senden von E-Mails aus meiner ASP.NET-Anwendung zu verwenden. Ich kann eine Verbindung zum Server herstellen, aber wenn ich versuche, mich zu...