Files
claude-resume-kit/job_scout/_fix_probe.py
T
dennisthiessenandClaude Opus 5 284407cd23 fix(scout): repair Roche/Apple, add Amazon+Axpo, make title filtering fail-open
Scraper fixes:
- Roche: new fetch_phenom adapter (Phenom refineSearch). The old playwright scrape
  of ?locationsearch=Switzerland harvested recommendation-widget cards (Shanghai,
  Kyiv, Bogota) while the page reported no-results. 0 -> 88 CH-eligible roles.
- Apple: dropped default_location "Switzerland", which relabelled US "Various
  Locations" postings as Swiss (84 phantom CH rows over 4 runs). Now honestly 0.
- Meta: NOT broken — metacareers reports "1 Items" for Zurich. Comment added so it
  is not "fixed" again.

New boards:
- Amazon/AWS (fetch_amazon): 32 CH roles incl. a Zurich AWS FDE req and a Bern
  ProServe Cloud Architect. AWS is the evidenced cloud; claims.json forbids GCP.
- Axpo (teamtailor via base_url + pagination): 461 roles, opens the energy lane.
  Locations read from schema.org jobLocation with ISO alpha-2 expanded, so
  Madrid/Milan/Warsaw roles are not marked Swiss. Telenor benefits too.

Title filtering now has two explicit modes. Inclusion allowlists fail closed and
hide unanticipated good-fit roles, so they are now used only where volume forces
it (>~200 roles). Everything else uses the shared, board-agnostic
NOISE_TITLE_EXCLUDE, which fails open and leaves the final call to the scorer and
the reviewer. Palantir stays unfiltered per its existing documented rationale.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 11:17:24 +02:00

32 lines
1.4 KiB
Python

import io, json
from playwright.sync_api import sync_playwright
SITES = {
'roche': 'https://careers.roche.com/global/en/search-results?keywords=&locationsearch=Switzerland',
'meta': 'https://www.metacareers.com/jobs?offices[0]=Zurich%2C%20Switzerland',
'apple': 'https://jobs.apple.com/en-us/search?location=switzerland-CHE',
}
out = io.open('_fix_out.txt', 'w', encoding='utf-8')
with sync_playwright() as p:
b = p.chromium.launch()
for k, u in SITES.items():
pg = b.new_page(); calls = []
def on_resp(r, calls=calls):
ct = r.headers.get('content-type', '')
if 'json' in ct and r.request.method in ('GET', 'POST'):
calls.append((r.request.method, r.url, r.request.post_data))
pg.on('response', on_resp)
try:
pg.goto(u, wait_until='domcontentloaded', timeout=60000)
pg.wait_for_timeout(9000)
pg.mouse.wheel(0, 5000); pg.wait_for_timeout(4000)
out.write('== %s\n' % k)
for m, url, pd in calls:
if any(w in url.lower() for w in ('search', 'job', 'graphql', 'widget', 'role')):
out.write(' %s %s\n' % (m, url[:190]))
if pd: out.write(' POST %s\n' % pd[:600])
except Exception as e:
out.write('== %s ERR %s\n' % (k, str(e)[:150]))
pg.close()
b.close()
out.close()