尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

使用DrissionPage高效爬取招聘网站数据的实战指南

使用DrissionPage高效爬取招聘网站数据的实战指南 1. 项目概述与背景最近在技术社区中使用DrissionPage进行网页数据采集的需求逐渐增多。这个Python库提供了一种混合驱动Chromium和requests的网页自动化方案特别适合处理动态加载内容和反爬机制较为严格的网站。本文将分享如何利用DrissionPage高效爬取某招聘网站数据的具体实现方案。2. 技术选型分析2.1 DrissionPage核心优势DrissionPage相比传统爬虫工具具有三大独特优势混合驱动架构可无缝切换浏览器模式和纯请求模式在需要执行JavaScript的页面使用Chromium驱动在静态页面切换为轻量级requests模式显著提升采集效率智能等待机制内置多种元素定位策略和等待条件能自动处理动态加载内容避免传统方案中复杂的sleep设置反反爬能力支持自动管理cookies、随机化User-Agent、请求间隔控制等反检测措施2.2 目标网站特点分析某招聘网站作为国内主流招聘平台其反爬机制主要包括动态渲染的职位列表需要执行JS关键数据接口加密需要解析API请求请求频率限制需要合理控制采集节奏验证码触发机制需要避免触发条件3. 环境准备与配置3.1 基础环境安装# 安装DrissionPage核心库 pip install drissionpage # 推荐搭配使用的数据处理库 pip install pandas openpyxl3.2 浏览器驱动配置DrissionPage默认使用Chromium内核推荐配置from drissionpage import ChromiumPage # 初始化配置 page ChromiumPage( headlessFalse, # 调试时可设为可见模式 proxyNone, # 如有需要可配置代理 user_agentNone # 自动使用随机UA )注意首次运行会自动下载Chromium驱动请确保网络通畅4. 核心爬取流程实现4.1 页面登录与会话保持def login(username, password): page.get(https://login.xxx.com) page.ele(idusername).input(username) page.ele(idpassword).input(password) page.ele(tag:buttontext登录).click() page.wait.load_start() # 等待页面跳转 # 保存cookies避免重复登录 cookies page.cookies return cookies4.2 职位列表采集策略def get_job_list(keyword, max_page10): jobs [] base_url fhttps://search.xxx.com/list?keyword{keyword} for page_num in range(1, max_page1): url f{base_url}page{page_num} page.get(url) # 等待列表加载完成 page.wait.ele_loaded(classjob-item) # 提取当前页职位信息 items page.eles(classjob-item) for item in items: job { title: item.ele(classtitle).text, company: item.ele(classcompany).text, salary: item.ele(classsalary).text, link: item.ele(taga).attr(href) } jobs.append(job) # 随机延迟防止封禁 page.wait.random(2, 5) return pd.DataFrame(jobs)4.3 详情页数据提取技巧def get_job_detail(url): page.get(url) # 处理弹窗干扰 if page.ele(classpopup, timeout2): page.ele(classclose-btn).click() # 关键数据提取 detail { description: page.ele(classjob-detail).text, requirements: page.ele(classrequirements).text, address: page.ele(classoffice-address).text, publish_time: page.ele(classtime).text } # 处理分页描述 while True: if page.ele(text下一页, timeout1): page.ele(text下一页).click() page.wait.load_start() detail[description] \n page.ele(classjob-detail).text else: break return detail5. 反爬应对方案5.1 请求频率控制# 在配置中设置全局请求间隔 page.set.load_strategy( interval(3, 8), # 随机间隔3-8秒 retry_times3, # 失败重试次数 timeout30 # 超时时间 )5.2 IP轮换策略# 使用代理池示例 proxies [ http://proxy1.example.com, http://proxy2.example.com ] def rotate_proxy(): proxy random.choice(proxies) page.set.proxy(proxy)5.3 验证码处理方案def handle_captcha(): if page.ele(idcaptcha, timeout3): captcha_img page.ele(idcaptcha-img) captcha_img.screenshot(captcha.png) # 这里接入第三方验证码识别服务 code input(请输入captcha.png中的验证码: ) page.ele(idcaptcha-input).input(code) page.ele(idconfirm-btn).click() return True return False6. 数据存储与处理6.1 结构化存储方案def save_to_excel(data, filename): # 使用pandas进行数据清洗 df pd.DataFrame(data) # 薪资范围拆分示例 df[[min_salary, max_salary]] df[salary].str.extract( r(\d)k-(\d)k ).astype(float) # 保存为Excel df.to_excel(filename, indexFalse)6.2 增量采集实现def incremental_update(filename): try: old_df pd.read_excel(filename) existing_urls set(old_df[link]) except: existing_urls set() new_jobs [job for job in all_jobs if job[link] not in existing_urls] if new_jobs: update_df pd.DataFrame(new_jobs) update_df.to_excel(filename, modea, headerFalse, indexFalse)7. 常见问题排查7.1 元素定位失败处理# 更健壮的元素定位方式 element page.ele(classjob-item, timeout5) if not element: # 尝试备用定位方案 element page.ele(tag:liclass:contains(job), timeout3) if not element: print(元素定位失败当前页面:, page.title) page.screenshot(error.png) return None7.2 页面跳转异常监控# 在关键操作后添加状态检查 page.ele(text下一页).click() if not page.wait.load_start(timeout10): print(页面跳转超时) page.refresh()7.3 内存泄漏预防# 定期清理页面缓存 if len(page.tabs) 5: page.close_other_tabs() page.clear_cache()8. 性能优化建议8.1 并行采集方案from concurrent.futures import ThreadPoolExecutor def parallel_crawl(urls): with ThreadPoolExecutor(max_workers4) as executor: results list(executor.map(get_job_detail, urls)) return results8.2 请求缓存机制# 使用磁盘缓存示例 from requests_cache import CachedSession session CachedSession(demo_cache) page.set.session(session) # 替换默认session8.3 资源使用监控import psutil def check_system(): if psutil.virtual_memory().percent 90: print(内存使用过高建议清理) if len(page.tabs) 10: print(浏览器标签页过多建议重启)9. 完整代码示例from drissionpage import ChromiumPage import pandas as pd import random import time class JobSpider: def __init__(self): self.page ChromiumPage( headlessTrue, load_modeeager, # 平衡模式 timeout30 ) self.page.set.load_strategy( interval(2, 5), retry_times3 ) def crawl(self, keyword, max_page5): try: # 登录获取会话 self.login() # 采集列表页 jobs self.get_job_list(keyword, max_page) # 并行采集详情 details self.parallel_get_details(jobs[link].tolist()) # 合并数据 full_data pd.merge(jobs, details, onlink) return full_data finally: self.page.quit() # 其他方法实现...10. 法律与伦理注意事项严格遵守目标网站的robots.txt协议采集频率控制在合理范围建议≤1请求/3秒不采集个人隐私信息如联系方式等数据仅用于个人学习研究商业使用需获得平台授权在实际项目中建议先通过官方API获取数据当API无法满足需求时再考虑网页采集方案。同时要注意数据使用的合规性避免法律风险。
返回列表