|
|
|
|
@ -21,14 +21,17 @@ class LinkedInAdapter(ManifestDrivenAdapter):
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def _scroll_to_load(page) -> None:
|
|
|
|
|
"""Scroll each job card into view to force LinkedIn's virtual list to render."""
|
|
|
|
|
"""Scroll each card into view one by one so LinkedIn renders all occluded items."""
|
|
|
|
|
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)
|
|
|
|
|
count = page.evaluate(
|
|
|
|
|
"document.querySelectorAll('li[data-occludable-job-id]').length"
|
|
|
|
|
)
|
|
|
|
|
for i in range(count):
|
|
|
|
|
page.evaluate(f"""() => {{
|
|
|
|
|
const cards = document.querySelectorAll('li[data-occludable-job-id]');
|
|
|
|
|
if (cards[{i}]) cards[{i}].scrollIntoView({{behavior: 'instant', block: 'center'}});
|
|
|
|
|
}}""")
|
|
|
|
|
page.wait_for_timeout(120)
|
|
|
|
|
logger.debug(f"[linkedin] Scrolled through {count} cards")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.debug(f"[linkedin] scroll_to_load failed: {e}")
|
|
|
|
|
|