{“output”:“Ich baue einen täglichen Digest-Workflow auf, der Inhalte aus HVAC-Branchenblog bezieht. Drei meiner Quellen (HouseCall Pro, Jobber Academy, HVAC Informed) sind durch Cloudflare geschützt. Wenn mein HTTP Request Node diese URLs aufruft, erhalte ich eine 403 “Just a moment…”-Cloudflare-Challenge-Seite statt des eigentlichen Inhalts.\n\nDiese Seiten haben auch keine RSS-Feeds, daher funktionieren RSS Feed Read Nodes nicht.\n\n\nWas ich bereits versucht habe:\n\n* HTTP Request Node (GET) — gibt Cloudflare Challenge HTML zurück\n\n* RSS Feed Read Node — gibt XML Parse Fehler zurück (Seiten sind keine RSS)\n\n\nFragen:\n\n1. Gibt es eine Möglichkeit, den Cloudflare Bot-Schutz nativ in n8n zu umgehen?\n\n2. Sollte ich Apify, ScrapingBee oder BrightData für diese Quellen verwenden?\n\n3. Gibt es einen Community Node, der Cloudflare-geschützte Seiten handhabt?\n\n4. Würde das Hinzufügen von browsähnlichen Headern (User-Agent, Accept-Language, etc.) helfen?”}
@Asim_Arman hat eine schnelle Überprüfung deiner 3 Quellen gemacht, bevor ich etwas empfehle, und es gibt gute Nachrichten für eine davon — HouseCall Pro ist eigentlich nicht auf Cloudflare und sein /feed/ funktioniert einwandfrei, wenn du einfach einen echten Browser User-Agent Header zum HTTP Request Node hinzufügst. getestet mit einem Mozilla/5.0 UA gegen Housecall Pro und habe valides RSS XML zurückbekommen. dein 403 dort kommt fast sicher daher, dass n8ns HTTP Request Node standardmäßig einen generischen UA (oder gar keinen) verwendet und die Site einen einfachen UA Filter hat. wechsel zu RSS Feed Read mit Housecall Pro und einem User-Agent Override und fertig für diesen, kein Scraping nötig.
Jobber (getjobber.com) ist tatsächlich auf Cloudflare — cf-ray Header ist in den Responses vorhanden — und es gibt kein RSS für den Academy Bereich. HVAC Informed stellt auch kein RSS zur Verfügung. diese beiden brauchen wirklich einen Scraping Service.
zur Frage des Cloudflare-Bypass nativ in n8n: es gibt da keinen echten Weg. ihre Challenge erfordert die Ausführung von JS zum Lösen von Proof-of-Work plus Behavioral Fingerprinting, und der HTTP Request Node ist ein normaler HTTP Client ohne Browser Engine. die cloudscraper-artigen libs aus 2022-2023 funktionieren alle nicht mehr gegen aktuelles Cloudflare, also funktionieren auch die wenigen Community Nodes, die sie wrappen, nicht.
browser-ähnliche Header beheben einfache UA Filter (was HouseCall Pros 403 tatsächlich war, ironischerweise) aber tun nichts gegen die echte Cloudflare Challenge — sie machen Fingerprinting von TLS, JA3, Request Timing und JS Ausführung über Headers hinaus.
für ScrapingBee vs Apify vs BrightData — für dein Use Case (geringes Volumen täglich, nur 2 Sites brauchen echtes Scraping) sind ScrapingBee oder Firecrawl das Sauberste. grober Vergleich:
{
"scrapingbee": {"per_request": "~$0.001-0.005", "fit": "niedriges bis mittleres Volumen, einfach, schnell"},
"scraperapi": {"per_request": "~$0.001-0.003", "fit": "vergleichbar mit scrapingbee"},
"firecrawl": {"per_request": "~$0.001", "fit": "scrape-to-markdown, LLM-ready Output"},
"brightdata": {"per_request": "~$0.005-0.02", "fit": "härteste Ziele, teuer aber zuverlässigste"},
"apify": {"per_request": "variabel", "fit": "komplexe Multi-Page Flows"}
}
ScrapingBee aufgerufen via HTTP Request sieht so aus:
{
"method": "GET",
"url": "https://app.scrapingbee.com/api/v1/",
"qs": {
"api_key": "<your_key>",
"url": "https://www.getjobber.com/academy/",
"render_js": "true",
"premium_proxy": "true"
}
}
Endstand ist ein RSS Feed Read für HouseCall Pro, zwei ScrapingBee HTTP Calls für Jobber und HVAC Informed, dann parse → digest. viel billiger als alle 3 als Cloudflare-geschützt zu behandeln, wenn nur einer tatsächlich welche ist.
Vielen Dank!, Ich probiere das aus und berichte dir.
Gerne! Sag mir Bescheid, wie es funktioniert!
Ich möchte hinzufügen, dass Apify den Smart Article Extractor hat, der (normalerweise) Artikel-Links auf einer Seite automatisch erkennt und sie dann einzeln ausliest.
Und er emuliert einen Browser, sodass er auch Cloudflare umgehen kann. Es ist auch ein Actor mit reiner Nutzungsgebühr, sodass ein täglicher Aufruf für drei Blogs wahrscheinlich in ihren kostenlosen Plan passt.
Für allgemeinere (nicht-Artikel-)Fälle kannst du strukturierte Inhalte erhalten, indem du ihren Website Content Crawler verwendest und diese dann durch ein kleines KI-Modell wie Haiku oder GPT-Minis verarbeitest.
Für komplexere Websites wie Jobber und HVAC Informed gilt: Falls du eine selbst gehostete n8n-Instanz mit Docker nutzt und kostenpflichtige Lösungen vermeiden möchtest, ist eine interessante Alternative die Ausführung von SeleniumBase im Undetected ChromeDriver (UC) Modus in einem separaten Docker-Container. Der UC (Undetected ChromeDriver) Modus von SeleniumBase ist derzeit eines der robustesten Open-Source-Tools zum Umgehen von Cloudflare-Schutzmaßnahmen.
Du kannst diesen Container dann so konfigurieren, dass deine Scraping-Skripte darin ausgeführt werden, und diese anschließend direkt aus n8n über den Execute Command-Node auslösen (oder mit Hilfe eines benutzerdefinierten Tools, falls du deinen Workflow um einen n8n KI-Agent strukturiert hast.
Eine Sache, die noch niemand erwähnt hat: Bevor du eine Scraping-Service in Anspruch nimmst, schau nach, ob diese Websites eine Sitemap oder einen Atom-Feed unter einem nicht standardmäßigen Pfad haben.
Versuche diese zu testen, bevor du für etwas zahlst:
- /sitemap.xml
- /sitemap_index.xml
- /feed/
- /atom.xml
- /blog/feed/ oder /blog/rss/
Viele WordPress/HubSpot-betriebene Blogs (die sowohl HouseCall Pro als auch Jobber nutzen) haben Feeds aktiviert, aber nicht im verlinkt. Der RSS Read Node funktioniert perfekt, wenn du die richtige URL triffst.
Für diejenigen, die wirklich keinen Feed haben und Cloudflare blockiert dich:
Günstigster produktives Approach: Firecrawl oder ScrapingBee über HTTP Request Node.
HTTP Request → POST https://api.firecrawl.dev/v1/scrape
Headers: Authorization: Bearer [YOUR_API_KEY]
Body: { “url”: “https://target.com/blog”, “formats”: [“markdown”] }
Liefert sauberes Markdown zurück — kein HTML-Parsing nötig. Führe es über einen Schedule Trigger einmal täglich aus. Bei 3 Websites × 1 Request/Tag bleibst du weit innerhalb jedes kostenlosen Plans.
Produktion Hardening (der Teil, den die meisten Tutorials überspringen):
- Füge einen Retry mit Backoff am HTTP Request Node hinzu — Scraping-APIs geben dir gelegentlich 429
- Speichere den Hash der zuletzt abgerufenen URL in einer Postgres-Tabelle, damit du denselben Artikel morgen nicht erneut verarbeitest (Idempotenz)
- Füge einen Error Trigger Workflow hinzu — wenn dein Digest am Montag stillschweigend fehlschlägt, willst du das vor Freitag wissen
Der “einfach scrapen”-Teil ist einfach. Es 6 Monate lang zuverlässig täglich zum Laufen zu bringen, ohne stille Fehler, ist dort, wo die meisten täglichen Digest-Workflows scheitern.
Hey, ich schätze die detaillierte Erklärung wirklich, achamm. Das war super hilfreich und ich bin den meisten Schritten gefolgt.
Das habe ich genau befolgt:
-
HouseCall Pro - bestätigt, dass es nicht Cloudflare war, den User-Agent-Header zum HTTP-Request-Node hinzugefügt, auf
/feed/verwiesen, alles durch einen XML-Node und dann einen Code-Node geleitet. Funktioniert jetzt perfekt. -
Jobber und HVAC Informed - Firecrawl statt ScrapingBee verwendet (gleiche Preiskategorie, die du erwähnt hast, mir gefiel nur die Markdown-Ausgabe besser, um sie an Claude weiterzugeben).
Zwei-Schritte-Ansatz: erst die Listing-Seite scrapen, um die Artikel-URLs zu extrahieren, dann jeden Artikel einzeln über einen zweiten HTTP-Request scrapen.
Was wir über deine Empfehlungen hinaus noch hinzugefügt haben:
- Einen Parse Code Node nach jedem Firecrawl-Request, um alle Quellen in identische Felder (title, content, link, feedSource) zu normalisieren, bevor sie zusammengeführt werden
Danke dir, sehr hilfreich, dass du in der Community dabei bist
Gerne geschehen, wir freuen uns, dass wir dir helfen konnten!
Wenn du die Möglichkeit hast, ein Tool selbst zu hosten (z. B. über Docker auf demselben Server wie dein n8n) und du die Quota-Limits von kostenpflichtigen Plattformen (wie Apify, ScrapingBee oder Firecrawl) vermeiden möchtest, solltest du dir FlareSolverr anschauen.
Es ist ein Open-Source-Proxy, der im Hintergrund einen Headless-Browser startet, um die Cloudflare-Herausforderung zu lösen und dir den rohen HTML-Code der Seite zurückzugeben. Du musst ihn nur lokal mit einem einfachen HTTP-Request-Knoten in n8n abfragen.
Allerdings gibt dir FlareSolverr nur den rohen HTML-Code zurück. Du musst daher einen HTML-Knoten oder einen Code-Knoten direkt danach hinzufügen, um die Daten selbst zu parsen und in JSON zu strukturieren.
ein kleines Beispiel:
{
“nodes”: [
{
“parameters”: {
“jsCode”: “const html = $json.solution.response;\n\nfunction getText(html, startMarker, endMarker) {\n const start = html.indexOf(startMarker);\n if (start === -1) return ‘’;\n const end = html.indexOf(endMarker, start);\n if (end === -1) return ‘’;\n return html.substring(start + startMarker.length, end).trim();\n}\n\nfunction getMetaContent(html, name) {\n const regex = new RegExp(<meta name=\"${name}\" content=\"([^\"]+)\", ‘i’);\n const match = html.match(regex);\n return match ? match[1] : ‘’;\n}\n\nlet title = getText(html, ‘<h1 class="story-title">’, ‘’);\n// entfernt HTML-Tags aus dem Titel\ntitle = title.replace(/<a[^>]>([^<])</a>/, ‘$1’).trim();\n\nconst description = getMetaContent(html, ‘description’);\n\nlet content = getText(html, ‘<div class="articlebody clear cf" id="articlebody">’, ‘<div class="stophere" id="hiddenH1">’);;\n// bereinigt den Inhalt\ncontent = content\n .replace(/<script[^>]>[\s\S]?</script>/gi, ‘’)\n .replace(/<style[^>]>[\s\S]?</style>/gi, ‘’)\n .replace(/<[^>]+>/g, ’ ')\n .replace(/\s+/g, ’ ')\n .trim();\n\nreturn [{\n title: title,\n description: description,\n content: content\n}];”
},
“type”: “n8n-nodes-base.code”,
“typeVersion”: 2,
“position”: [
-912,
4480
],
“id”: “a6275095-c4ed-427f-a791-620bcd83710b”,
“name”: “Extract from HTML”
},
{
“parameters”: {
“method”: “POST”,
“url”: “=http://flaresolverr:8191/v1”,
“sendHeaders”: true,
“headerParameters”: {
“parameters”: [
{
“name”: “Content-Type”,
“value”: “application/json”
}
]
},
“sendBody”: true,
“bodyParameters”: {
“parameters”: [
{
“name”: “cmd”,
“value”: “request.get”
},
{
“name”: “url”,
“value”: “={{ $json.url }}”
},
{
“name”: “maxTimeout”,
“value”: 90000
}
]
},
“options”: {
“timeout”: 120000
}
},
“type”: “n8n-nodes-base.httpRequest”,
“typeVersion”: 4.4,
“position”: [
-1120,
4480
],
“id”: “4c884f8a-09c7-4c13-b7e8-ac38098b00f6”,
“name”: “FlareSolverr”,
“retryOnFail”: true
}
],
“connections”: {
“Extract from HTML”: {
“main”: [
]
},
“FlareSolverr”: {
“main”: [
[
{
“node”: “Extract from HTML”,
“type”: “main”,
“index”: 0
}
]
]
},
“pinData”: {},
“meta”: {
“templateCredsSetupCompleted”: true,
“instanceId”: “03428eda2f2a76af33393f7fa59419dea9e2e74e0d630500b36df8cf5b8e161d”
}
}