十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python爬虫实战:DrissionPage高效抓取动态招聘网站

Python爬虫实战:DrissionPage高效抓取动态招聘网站 1. DrissionPage爬虫工具简介DrissionPage是一个基于Python的现代化网页自动化工具它巧妙地将浏览器自动化与数据包抓取能力整合在一起。与传统的Selenium或Requests方案不同DrissionPage采用了一种混合模式——既能像浏览器一样渲染页面又能直接拦截和分析网络请求。这个工具特别适合处理动态加载的招聘网站比如某聘这类大量使用AJAX技术的平台。传统爬虫在面对这类网站时要么需要模拟完整浏览器行为性能低下要么得逆向解析复杂的API接口维护成本高。而DrissionPage的混合模式正好折中了这两个极端。实际测试中发现某聘前端采用了Vue.js框架职位列表通过异步接口加载页面URL不会随翻页变化。这正是DrissionPage最能发挥优势的场景。2. 环境准备与基础配置2.1 安装必要组件首先通过pip安装核心包建议使用虚拟环境pip install drissionpage对于国内用户可以添加清华源加速pip install drissionpage -i https://pypi.tuna.tsinghua.edu.cn/simple2.2 初始化浏览器配置创建config.py配置文件from DrissionPage import ChromiumOptions co ChromiumOptions() co.headless(False) # 调试时设为可见模式 co.set_paths(browser_path/path/to/chrome) # 指定浏览器路径 co.incognito(True) # 启用无痕模式 co.set_user_agent(Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36) # 设置UA # 反检测关键配置 co.set_argument(--disable-blink-featuresAutomationControlled) co.no_imgs(True) # 禁止加载图片提升速度3. 某聘网站结构分析3.1 页面加载机制解析通过开发者工具分析F12打开某聘的职位搜索页有几个关键特点首屏HTML只包含基础框架真实数据通过/search/joblist接口获取翻页采用POST请求携带加密参数pageNum和pageSize每个职位卡片有独立的positionId详情页URL格式为/job_detail/{id}.html3.2 关键接口识别使用DrissionPage的监听功能捕获网络请求from DrissionPage import SessionPage page SessionPage() page.listen.start(job_detail) # 监听包含job_detail的请求 page.get(https://www.zhipin.com/web/geek/job) print(page.listen.wait()) # 打印捕获的请求典型响应数据结构示例{ code: 200, data: { list: [ { positionId: 123456, title: Python开发工程师, salary: 20-40K, company: 某科技公司, skills: [Django, 爬虫] } ] } }4. 完整爬取实现4.1 搜索页爬取策略实现分页爬取的代码逻辑def crawl_positions(keyword, max_page10): positions [] for page in range(1, max_page 1): params { query: keyword, page: page, city: 101010100 # 北京城市代码 } resp page.post( https://www.zhipin.com/api/search/joblist, dataparams, headers{Referer: https://www.zhipin.com/} ) if resp.status_code ! 200: print(f第{page}页请求失败) continue data resp.json() positions.extend(parse_list(data[data][list])) # 随机延迟防止封禁 page.wait.random(2, 5) return positions4.2 详情页信息提取使用XPath定位关键元素def parse_detail(position_id): detail_url fhttps://www.zhipin.com/job_detail/{position_id}.html page.get(detail_url) return { title: page.ele(xpath://h1[classjob-title]/text()), salary: page.ele(xpath://span[classsalary]/text()), requirements: [ item.text for item in page.eles(xpath://div[contains(class, requirement)]/ul/li) ], description: page.ele(xpath://div[contains(class, detail-content)]).html }5. 反反爬策略实战5.1 指纹伪装技术在config.py中补充以下防御措施# 修改WebGL指纹 co.set_property(webgl.vendor, Intel Inc.) co.set_property(webgl.renderer, Intel Iris OpenGL Engine) # 修改屏幕参数 co.set_property(screen.width, 1366) co.set_property(screen.height, 768) co.set_property(screen.depth, 24) # 禁用WebRTC co.set_argument(--disable-webrtc)5.2 请求特征混淆定制请求中间件from random import choice class RequestMiddleware: def __init__(self): self.user_agents [...] self.referers [...] def before_request(self, request): request.headers.update({ Accept-Language: zh-CN,zh;q0.9, X-Forwarded-For: f192.168.{randint(1,255)}.{randint(1,255)}, User-Agent: choice(self.user_agents), Referer: choice(self.referers) }) return request6. 数据存储与清洗6.1 结构化存储方案使用MongoDB存储的完整示例from pymongo import MongoClient from datetime import datetime class Storage: def __init__(self): self.client MongoClient(mongodb://localhost:27017/) self.db self.client[job_crawler] def save_position(self, data): data[crawl_time] datetime.now() self.db.positions.update_one( {positionId: data[positionId]}, {$set: data}, upsertTrue )6.2 数据清洗技巧处理薪资范围的实用函数def parse_salary(salary_str): if K in salary_str: nums re.findall(r(\d)K, salary_str) if - in salary_str: # 20-40K格式 return [int(n) * 1000 for n in nums] else: # 20K以上格式 return int(nums[0]) * 1000 # 其他格式处理...7. 实战经验与避坑指南登录态保持某聘的Cookies有效期约2小时建议使用账号池轮换。实测发现__zp_stoken__是最关键的字段。流量控制单个IP的请求频率建议控制在列表页30秒/页详情页5-10秒/个 使用代理IP时也要注意切换频率。元素定位陷阱某聘的DOM结构会不定期微调建议采用容错定位策略title (page.ele(xpath://h1[contains(class,title)]/text()) or page.ele(xpath://h1[classjob-name]/text()))验证码应对当触发验证时立即暂停爬取手动处理完验证后更换UserAgent和IP再继续。
返回列表