You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium如何滚动双栏页面中间职位列表加载全部职位数据

问题原因

你的滚动逻辑全部失效是因为搞错了滚动主体:该页面的职位列表是独立的溢出滚动容器,滚动条挂载在class为vacancies__list的DOM节点上,既不是全局window对象,也不是你选中的h3标题子元素。对非滚动主体执行滚动、发送按键操作,自然无法触发列表的懒加载。
另外你的代码还有两个逻辑bug:

  • 只在首次进入页面时获取了一次职位列表节点集合,后续滚动加载的新条目不会被自动加入这个集合
  • 存在语法错误:driver.execute.script写法错误,正确API为driver.execute_script;旧版find_element_by_*系列方法在高版本Selenium中已被废弃,运行会抛异常。
修复方案

1. 针对滚动容器做定向滚动

不要操作全局window,直接定位到职位列表的滚动容器,通过JS控制它的滚动位置,同时通过容器滚动高度判断是否已经加载完全部职位,示例代码如下:

# 等待职位列表容器加载完成
scroll_container = WebDriverWait(driver, 15).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, ".vacancies__list"))
)

last_container_height = driver.execute_script("return arguments[0].scrollHeight", scroll_container)
# 循环滚动加载所有职位
while True:
    # 滚动到当前列表底部
    driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", scroll_container)
    time.sleep(2.5) # 等待懒加载接口返回、新条目渲染完成
    # 计算滚动后的新高度
    new_container_height = driver.execute_script("return arguments[0].scrollHeight", scroll_container)
    if new_container_height == last_container_height:
        # 高度不再变化说明已经到达列表底部,没有更多职位
        break
    last_container_height = new_container_height

2. 调整采集逻辑

等所有职位条目全部加载完成后,再统一解析列表页的所有职位链接,之后逐个访问详情页采集字段,不要边滚动边采集,避免出现漏采、重复采集的问题:

# 全部加载完成后再解析所有列表项
soup = BeautifulSoup(driver.page_source, 'html.parser')
lists = soup.find_all('div', {'class': 'list__item'})
jobs_list = []

for _list in lists:
    link = _list.find('a', class_="list__item__text")["href"]
    current_url = "https://jobsearch.az" + link
    driver.get(current_url)
    # 等待详情页职位标题加载完成再解析,替换固定10秒等待提升效率
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CLASS_NAME, "vacancy__title"))
    )
    soup = BeautifulSoup(driver.page_source, 'html.parser')
    job = soup.find('div', {'class': 'vacancy'})
    
    # 提取字段逻辑和原有逻辑一致
    company = job.find('div', class_="vacancy__start").text.strip()
    category = job.find('span', class_="company__industry").text.strip()
    job_title = job.find('h1', class_="vacancy__title").text.strip()
    deadline = job.find('span', class_="vacancy__deadline").text.strip()
    views = _list.find('div', class_="list__item__end").text.strip()
    
    jobs_list.append({
        "job_title": job_title,
        "company": company,
        "category": category,
        "deadline": deadline,
        "views": views
    })

# 后续转DataFrame、关闭浏览器逻辑保持原有即可
其他优化建议
  • 去掉循环中无意义的窗口最大化、最小化操作,频繁操作窗口状态反而可能导致页面失焦、元素加载异常
  • 所有固定的time.sleep()等待尽量替换为显式等待,判断目标元素加载完成后再执行后续操作,能大幅降低采集耗时,同时减少因为网络波动导致的元素找不到异常
  • 可以在访问详情页采集时保留列表页的窗口句柄,采集完单个详情后直接切回列表页,比反复调用driver.get()访问列表、详情页效率更高

内容的提问来源于stack exchange,提问作者nihad aliyev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 15:21:26