You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

35 lines
1.3 KiB
Python

"""LinkedIn Jobs adapter — scroll to load all cards on first page only."""
from __future__ import annotations
from loguru import logger
from gimme_job.adapters.base import ManifestDrivenAdapter
from gimme_job.adapters.registry import register
from gimme_job.models.dto import JobPostingCandidate, RawJobCard
@register("linkedin")
class LinkedInAdapter(ManifestDrivenAdapter):
def collect_cards(self, page, manifest) -> list[RawJobCard]:
"""Scroll each card into view to trigger lazy-loading, then extract."""
self._scroll_to_load(page)
return super().collect_cards(page, manifest)
def normalize(self, raw: RawJobCard) -> JobPostingCandidate:
return super().normalize(raw)
@staticmethod
def _scroll_to_load(page) -> None:
"""Scroll each job card into view to force LinkedIn's virtual list to render."""
try:
page.evaluate("""() => {
const cards = Array.from(document.querySelectorAll('li[data-occludable-job-id]'));
cards.forEach(card => card.scrollIntoView({ behavior: 'instant', block: 'center' }));
}""")
page.wait_for_timeout(800)
page.evaluate("window.scrollTo(0, 0)")
page.wait_for_timeout(400)
except Exception as e:
logger.debug(f"[linkedin] scroll_to_load failed: {e}")