← Alle Insights

Web Scraping von Jobpostings als Signal.

Unternehmen sagen viel in Earnings-Calls — aber die ehrlichste Aussage über ihre Pläne machen sie, wenn sie Stellen ausschreiben. Wer ein Unternehmen versteht, das gerade 200 ML-Engineers in Austin einstellt, weiß mehr über die nächsten 18 Monate als jeder Aktienanalyst. Job-Posting-Daten sind eine der zugänglichsten und überraschend robustesten Alternative-Data-Quellen.

Warum Jobpostings ein Signal sind.

Eine offene Stelle ist ein Commitment: Recruitings kosten Zeit, Onboarding kostet Geld, und Unternehmen schreiben nicht zum Spaß aus. Wenn Nvidia in einem Quartal seine offenen Engineering-Rollen um 35 % erhöht, signalisiert das eine Investitionsphase. Wenn Meta dieselbe Zahl um 40 % senkt — bei gleichzeitigem Sprung in Operations-Rollen mit Stichwort „efficiency" — signalisiert das eine Konsolidierungsphase mit Margin-Improvements.

Akademische Studien (am bekanntesten Gutierrez et al., 2021) zeigen, dass Veränderungen in Job-Postings gemittelt über ein Quartal mit einem Zeitvorlauf von zwei bis drei Quartalen statistisch signifikant mit der Umsatz- und Personalkosten-Entwicklung korrelieren. Der Effekt ist sektorabhängig: am stärksten in Tech und Biotech, am schwächsten in Commodities und Versorgern.

Datenquellen: Eigenbau versus Einkauf.

Es gibt drei Wege an die Daten. Erstens: Eigenbau direkt von den Karriere-Seiten der Unternehmen. Zweitens: Aggregatoren wie LinkedIn, Indeed, Glassdoor crawlen. Drittens: fertige Datenfeeds von Anbietern wie LinkUp, Burning Glass / Lightcast oder Revelio Labs einkaufen.

Für den Hands-on-Einstieg empfehle ich den Eigenbau auf einem überschaubaren Universum (S&P-500-Tech-Subsektor, etwa 80 Unternehmen). Sie verstehen die Datenqualität, die Edge-Cases und die rechtlichen Fallstricke deutlich besser, wenn Sie die Pipeline selbst aufbauen — und können später entscheiden, ob ein Vendor-Einkauf den Aufwand wert ist.

Scraping-Pipeline: Robust und respektvoll.

Eine produktive Scraping-Pipeline besteht aus drei Schichten: dem Discovery-Layer, der entscheidet, welche URLs gecrawlt werden, dem Fetch-Layer, der Inhalte abruft und Fehler verarbeitet, und dem Parse-Layer, der strukturierte Felder extrahiert (Titel, Standort, Team, Datum).

import asyncio
import httpx
from bs4 import BeautifulSoup
from datetime import datetime
import polars as pl

class JobScraper:
    def __init__(self, rate_limit=1.0):
        self.rate_limit = rate_limit  # Sekunden zwischen Requests
        self.headers = {
            'User-Agent': 'MGCapital-Research/1.0 (research@example.com)'
        }

    async def fetch_company_jobs(self, company, careers_url):
        """Lädt Stellenanzeigen für ein Unternehmen mit Höflichkeit."""
        async with httpx.AsyncClient(timeout=30) as client:
            await asyncio.sleep(self.rate_limit)
            try:
                r = await client.get(careers_url, headers=self.headers,
                                     follow_redirects=True)
                r.raise_for_status()
            except httpx.HTTPError as e:
                return {'company': company, 'error': str(e), 'jobs': []}

            soup = BeautifulSoup(r.text, 'lxml')
            jobs = self.parse_jobs(soup, company)
            return {
                'company': company,
                'fetched_at': datetime.utcnow(),
                'job_count': len(jobs),
                'jobs': jobs,
            }

    def parse_jobs(self, soup, company):
        """
        Unternehmensspezifischer Parser — in der Praxis pro Karriere-Seite
        eine eigene Implementierung mit JSON-Schema oder DOM-Selektoren.
        """
        jobs = []
        for posting in soup.select('div.job-posting'):
            jobs.append({
                'title': posting.select_one('.title').get_text(strip=True),
                'location': posting.select_one('.location').get_text(strip=True),
                'team': posting.select_one('.team').get_text(strip=True),
                'company': company,
            })
        return jobs

Wichtig: Respektieren Sie robots.txt, identifizieren Sie sich mit einem echten User-Agent, rate-limiten Sie Requests und cachen Sie Ergebnisse. Wer mit 50 parallelen Threads auf die Karriereseite eines Mittelständlers loslegt, wird zu Recht ausgesperrt — und es ist juristisch auch nicht sauber. Eine vernünftige Pipeline läuft einmal pro Nacht über ein Universum von wenigen hundert Unternehmen.

Klassifikation: Vom Titel zur Signalkategorie.

Die Roh-Stellentitel sind chaotisch. „Senior Machine Learning Engineer III", „Staff ML Scientist, Trust & Safety", „Lead Researcher — Foundation Models" — alles im Grunde das gleiche, aber für einen aggregierten Indikator brauchen Sie normalisierte Kategorien. Hier kommt entweder ein klassischer Klassifikator (TF-IDF + Logistic Regression) oder ein moderner LLM-basierter Ansatz infrage.

from anthropic import Anthropic
import json

client = Anthropic()

def classify_jobs_batch(job_titles, taxonomy):
    """
    Klassifiziert eine Liste Job-Titel in vorgegebene Kategorien via LLM.
    Kosten-effizient: ein Call für bis zu 200 Titel.
    """
    prompt = f"""Klassifiziere jeden Job-Titel in genau eine Kategorie aus:
{json.dumps(taxonomy, indent=2)}

Job-Titel:
{json.dumps(job_titles, indent=2)}

Antworte als JSON-Liste mit {{title, category, confidence}}."""

    msg = client.messages.create(
        model='claude-opus-4-7',
        max_tokens=4000,
        messages=[{'role': 'user', 'content': prompt}],
    )
    return json.loads(msg.content[0].text)

TAXONOMY = {
    'ai_research': 'KI-Forschung, Foundation Models, ML-Research',
    'ai_engineering': 'ML-Engineering, MLOps, Modell-Deployment',
    'platform_eng': 'Infrastruktur, Cloud, Data-Platform',
    'product_eng': 'Produkt-Engineering, Frontend, Backend-App',
    'sales_marketing': 'Sales, Marketing, GTM',
    'operations': 'Operations, Support, Compliance',
}

Wenn Sie eine Kategorie wie „ai_research" pro Unternehmen pro Monat zählen, sehen Sie sofort, welche Firmen massiv in Foundation-Model-Teams investieren — auch wenn die Earnings-Calls noch von „prudent capital allocation" sprechen. Das Delta zwischen Worten und Stellen ist oft die interessanteste Information.

Konkrete Strategien aus Job-Daten.

Drei Strategie-Familien funktionieren mit Job-Daten besonders gut:

Was Sie nicht aus Jobpostings ableiten können.

Ehrlich gesagt: kurzfristige Earnings-Surprises sind aus Job-Daten kaum zu extrahieren. Das Signal ist zu langsam — eine Stellenanzeige heute wird in zwei bis drei Quartalen sichtbar. Wer Job-Daten für Earnings-Plays auf ein Quartal hin nutzen will, wird systematisch enttäuscht. Auch Sektor-Top-Picks sind schwierig: ein hoher Hiring-Wert kann sowohl „Wachstum" als auch „verzweifeltes Aufstocken vor einer Restrukturierung" bedeuten.

Die Stärke der Daten liegt im mittleren Zeitfenster: drei bis 18 Monate. Wer sein Portfolio in diesem Horizont strukturiert und Jobpostings als einen von mehreren Inputs für die Positionsgewichtung nutzt, gewinnt ein konsistentes Plus an Sharpe — typischerweise 0,15 bis 0,3, je nach Sektor und Basis- Strategie.

Implementierungsfehler, die ich häufig sehe.

Erstens: Unternehmen ändern ihre Karriere-Plattformen. Workday, Greenhouse, Lever, eigene CMS — jedes mit eigener HTML-Struktur. Eine Pipeline, die heute funktioniert, bricht in drei Monaten an drei Stellen. Sie brauchen automatisierte Tests pro Parser und Alerts, wenn die erwartete Mindest-Anzahl Postings stark abweicht.

Zweitens: Re-Posting-Effekte. Manche Unternehmen veröffentlichen dieselbe Stelle alle 30 Tage neu, um den „neuesten Eintrag"-Bonus auf Job-Boards zu nutzen. Ohne Deduplizierung über Stellentitel + Standort + Team summieren Sie diese doppelt und übersehen die wahre Hiring-Aktivität.

Drittens: Sample-Bias. Wer nur Karriere-Seiten in englischer Sprache crawlt, sieht europäische Operationen vieler US-Konzerne nicht vollständig. Wer nur US-Standorte berücksichtigt, übersieht Offshore-Engineering in Indien und Polen. Sauberes geografisches Mapping ist mehr Arbeit, als die meisten Pipelines tatsächlich investieren.

Realistischer Aufbau für ein kleines Quant-Team.

Wenn Sie heute starten wollen, mit einem Team von ein bis zwei Personen und einem Universum von 200 US-Tech-Aktien: Drei Monate für Pipeline-Aufbau, Parser, Klassifikator und Datenbank. Sechs Monate für Backtest und Strategie-Kalibrierung. Drei Monate Paper-Trading. Nach einem Jahr haben Sie ein produktives System mit einem realistischen Edge im Bereich Sharpe 0,7 bis 1,1, das sich gut mit anderen Signalen kombinieren lässt. Es ist keiner der spektakulärsten Alternative-Datenquellen — aber eine der zugänglichsten und ehrlichsten.

Sie möchten eine Jobposting-Pipeline für Ihr Investment-Research aufbauen? Erstgespräch buchen — wir besprechen Universum, Compliance und Architektur.