Ontwikkel een Python Script voor Asynchrone Taken en Event-driven Programmeren
description
Met deze prompt kan de gebruiker leren hoe hij asynchrone workflows in Python efficiënt kan implementeren, wat leidt tot snellere en responsievere scripts bij taken waarbij wachten op I/O voorkomt. Het biedt diepgaande kennis van event-driven programmeren en praktische voorbeelden, waardoor het beter is dan standaard synchrone scripts.
prompt
Help me een Python script te schrijven dat asynchrone taken uitvoert met behulp van async en await. Beschrijf ook hoe event-driven programmeren werkt ...
try_prompt
generate_helper
disclaimerOnPageApi
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een overzicht en een voorbeeld van een Python-script dat asynchrone taken uitvoert met `async` en `await`, gericht op het gelijktijdig scrapen van meerdere webpagina's en het consolideren van de data.
### Hoe werkt event-driven programmeren in Python?
Event-driven programmeren is een programmeerstijl waarbij de software reageert op gebeurtenissen (zoals gebruikersinput, netwerkactiviteiten, timers). In Python gebeurt dit vaak via een event loop, die taken en gebeurtenissen beheert en afhandelt zodra ze klaar zijn. Dit maakt het mogelijk om meerdere taken gelijktijdig uit te voeren zonder dat je meerdere threads of processen nodig hebt.
### Voorbeeld met asyncio en aiohttp
Hier is een voorbeeld van een Python-script dat meerdere webpagina's gelijktijdig scrapeert met behulp van `asyncio` en `aiohttp`. We verzamelen de titel van elke pagina en slaan deze op in een dictionary.
```python
import asyncio
import aiohttp
from bs4 import BeautifulSoup
# Lijst van URL's om te scrapen
URLS = [
'https://example.com',
'https://python.org',
'https://github.com',
# Voeg meer URL's toe
]
async def fetch(session, url):
"""
Haalt de inhoud van een URL op en retourneert de titel van de pagina.
"""
try:
async with session.get(url) as response:
html = await response.text()
# Parse de HTML met BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
title = soup.title.string.strip() if soup.title else 'Geen titel gevonden'
return url, title
except Exception as e:
print(f"Fout bij ophalen {url}: {e}")
return url, None
async def main():
"""
Hoofdfunctie die meerdere URL's gelijktijdig verwerkt.
"""
results = {}
async with aiohttp.ClientSession() as session:
# Maak taken aan voor elke URL
tasks = [fetch(session, url) for url in URLS]
# Voer alle taken uit en wacht tot ze klaar zijn
for future in asyncio.as_completed(tasks):
url, title = await future
results[url] = title
print(f'{url} -> {title}')
# Consolideer of verwerk de resultaten verder
print("\nSamenvatting:")
for url, title in results.items():
print(f"{url}: {title}")
if __name__ == '__main__':
asyncio.run(main())
```
### Uitleg van het script:
- `fetch()` is een asynchrone functie die een URL ophaalt en de titel uit de HTML haalt.
- `main()` creëert een `aiohttp.ClientSession()` en start meerdere `fetch()` taken tegelijk.
- `asyncio.as_completed()` zorgt dat we de resultaten krijgen zodra ze klaar zijn, waardoor we efficiënt werken.
- Uiteindelijk worden alle titels geconsolideerd en weergegeven.
### Samenvatting
- Gebruik `async` en `await` om asynchrone taken te schrijven.
- `asyncio` beheert de event loop.
- `aiohttp` is ideaal voor asynchrone HTTP-aanvragen.
- Dit stelt je in staat om meerdere webpagina's tegelijk te scrapen, wat veel efficiënter is dan synchrone methoden.
Wil je het script uitbreiden of heb je specifieke data die je wilt verzamelen?
provider: deepseek
model: deepseek-chat
Hier is een Python script voor asynchrone web scraping met asyncio:
```python
import asyncio
import aiohttp
from bs4 import BeautifulSoup
import json
from typing import List, Dict
import time
class AsyncWebScraper:
def __init__(self):
self.session = None
self.results = []
async def fetch_page(self, url: str) -> str:
"""Asynchroon een webpagina ophalen"""
try:
async with self.session.get(url, timeout=30) as response:
return await response.text()
except Exception as e:
print(f"Fout bij ophalen {url}: {e}")
return ""
async def scrape_single_page(self, url: str) -> Dict:
"""Individuele pagina scrapen"""
html = await self.fetch_page(url)
if not html:
return {"url": url, "error": "Kon pagina niet ophalen"}
soup = BeautifulSoup(html, 'html.parser')
# Voorbeeld: extraheer titel en alle paragrafen
title = soup.find('title')
paragraphs = soup.find_all('p')
return {
"url": url,
"title": title.get_text() if title else "Geen titel",
"content": [p.get_text() for p in paragraphs][:5], # Eerste 5 paragrafen
"scraped_at": time.time()
}
async def scrape_multiple_pages(self, urls: List[str]) -> List[Dict]:
"""Meerdere pagina's parallel scrapen"""
async with aiohttp.ClientSession() as self.session:
tasks = [self.scrape_single_page(url) for url in urls]
results = await asyncio.gather(*tasks, return_exceptions=True)
self.results = [r for r in results if not isinstance(r, Exception)]
return self.results
def save_results(self, filename: str = "scraped_data.json"):
"""Resultaten opslaan naar JSON"""
with open(filename, 'w', encoding='utf-8') as f:
json.dump(self.results, f, ensure_ascii=False, indent=2)
async def main():
# Voorbeeld URLs
urls = [
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page3",
"https://example.com/page4"
]
scraper = AsyncWebScraper()
print("Start met scrapen...")
start_time = time.time()
await scraper.scrape_multiple_pages(urls)
end_time = time.time()
print(f"Scrapen voltooid in {end_time - start_time:.2f} seconden")
print(f"{len(scraper.results)} pagina's succesvol gescraped")
# Opslaan van resultaten
scraper.save_results()
print("Resultaten opgeslagen in scraped_data.json")
if __name__ == "__main__":
asyncio.run(main())
```
## Vereiste packages:
```bash
pip install aiohttp beautifulsoup4
```
## Uitleg Event-Driven Programmeren in Python:
**Event-driven programmeren** is een paradigma waarbij de programmastroom wordt bepaald door events (gebeurtenissen) in plaats van een sequentiële uitvoering. In Python wordt dit mogelijk gemaakt door:
### Kernconcepten:
1. **Event Loop**: Het hart van asynchrone programmering
2. **Coroutines**: Functies die kunnen pauzeren en hervatten
3. **Tasks**: Uitgevoerde coroutines
4. **Futures**: Placeholders voor toekomstige resultaten
### Hoe asyncio werkt:
```python
import asyncio
async def voorbeeld_taak(naam, wachttijd):
print(f"Start: {naam}")
await asyncio.sleep(wachttijd)
print(f"Klaar: {naam}")
return f"Resultaat {naam}"
async def main():
# Parallelle uitvoering
tasks = [
voorbeeld_taak("Taak 1", 2),
voorbeeld_taak("Taak 2", 1),
voorbeeld_taak("Taak 3", 3)
]
results = await asyncio.gather(*tasks)
print("Alle taken voltooid:", results)
# Uitvoeren
asyncio.run(main())
```
## Alternatieve libraries:
1. **Triple** (voor Django): `pip install django-triple`
2. **AnyIO**: `pip install anyio`
3. **HTTPX** (async HTTP client): `pip install httpx`
### HTTPX voorbeeld:
```python
import httpx
import asyncio
async def scrape_met_httpx(urls):
async with httpx.AsyncClient() as client:
tasks = [client.get(url) for url in urls]
responses = await asyncio.gather(*tasks)
return [response.text for response in responses]
```
Dit pattern is ideaal voor I/O-bound taken zoals web scraping, API calls, of database operaties waar je wilt wachten op externe responses zonder de hele applicatie te blokkeren.