当前位置: 首页 > ai >正文

实战案例:采集 51job 企业招聘信息

爬虫代理

本文将带你从零开始,借助 Feapder 快速搭建一个企业级招聘信息数据管道。在“基础概念”部分,我们先了解什么是数据管道和 Feapder;“生动比喻”用日常场景帮助你快速理解爬虫组件;“技术场景”介绍本项目中如何使用代理等采集策略;“实战案例”通过完整代码演示采集 51job 招聘信息并分类存储;最后在“扩展阅读”推荐一些进一步学习的资源。无论你是非技术背景的产品经理,还是校园里的同学,都能轻松上手,快速构建自己的企业级爬虫管道。

一、基础概念

1. 什么是数据管道?

  • 数据管道(Data Pipeline)指的是从数据源(如网页、API)到数据仓库(如数据库、文件)的整个流转过程,通常包括数据获取、清洗、存储和监控。
  • 在企业级场景下,管道需要稳定可靠、易于扩展,并支持重试、分布式、监控告警等能力。

2. 为什么选 Feapder?

  • 轻量易用:基于 Scrapy 设计理念,但更贴合现代 Python 开发习惯。
  • 分布式支持:内置分布式队列和调度,水平扩展无压力。
  • 插件丰富:支持自定义中间件、Pipeline,持久化、监控简单接入。
  • 示例生态:官方及社区提供多种行业示例,快速上手。

二、生动比喻

想象你要送快递:

  1. 分拣中心:接收并整理包裹(任务调度)
  2. 配送员:拿着包裹去各个地址(爬虫 Worker)
  3. 快递柜:存放收集好的包裹(Pipeline 存储)
  4. 后台系统:监控每个包裹的状态(监控告警)

Feapder 就是整个快递系统的“物流总控”,帮你把每个环节串起来,保证数据顺利、稳定地流转到最终存储。

三、技术场景

在企业级爬虫中,我们常常会遇到以下需求:

1. 使用代理 IP

  • 提升并发时避免 IP 限流和封禁
  • 引入爬虫代理:
# 亿牛云爬虫代理示例 www.16yun.cn
域名: proxy.16yun.cn 
端口: 12345  
用户名: 16YUN  
密码: 16IP

2. 设置 Cookie 和 User-Agent

  • Cookie:保持登录态或跑通多页
  • User-Agent:模拟浏览器请求,降低反爬几率

Feapder 支持在中间件中统一管理这些参数,代码简洁、易维护。

四、实战案例:采集 51job 企业招聘信息

下面我们以 https://www.51job.com 为例,演示如何用 Feapder 搭建完整的爬虫管道,采集岗位名称、职位信息、工作地址、薪资待遇,并分类存储到本地 JSON 文件。

1. 环境准备

# 安装 Feapder 及依赖
pip install feapder requests

2. 项目结构

feapder_job_pipeline/
├── spider.py         # 主爬虫脚本
├── settings.py       # 配置文件
└── pipelines.py      # 数据存储模块

3. 配置文件 settings.py

# settings.py# ---------- 分布式及队列配置(可选) ----------
# REDIS_HOST = "127.0.0.1"
# REDIS_PORT = 6379
# REDIS_PASSWORD = None# ---------- 代理设置 亿牛云代理示例 www.16yun.cn------
PROXY = {"domain": "proxy.16yun.cn", # 亿牛云代理域名"port": 8100,             # 代理端口"username": "16YUN",     # 代理用户名"password": "16IP",     # 代理密码
}# ---------- 中间件配置 ----------
DOWNLOADER_MIDDLEWARES = {# 自定义代理中间件"middlewares.ProxyMiddleware": 500,# Feapder 默认 UserAgent 中间件# "feapder.downloadermiddleware.useragent.UserAgentMiddleware": 400,
}# ---------- Pipeline 配置 ----------
ITEM_PIPELINES = {"pipelines.JsonPipeline": 300,
}

4. 自定义中间件 middlewares.py

# middlewares.py
import base64
from feapder import Requestclass ProxyMiddleware:"""通过亿牛云代理发送请求的中间件"""def process_request(self, request: Request):# 构造代理认证字符串auth_str = f"{request.setting.PROXY['username']}:{request.setting.PROXY['password']}"b64_auth = base64.b64encode(auth_str.encode()).decode()# 设置 request.meta 中的 proxyrequest.request_kwargs.setdefault("proxies", {"http": f"http://{request.setting.PROXY['domain']}:{request.setting.PROXY['port']}","https": f"http://{request.setting.PROXY['domain']}:{request.setting.PROXY['port']}"})# 注入 Proxy-Authorization 头request.request_kwargs.setdefault("headers", {})["Proxy-Authorization"] = f"Basic {b64_auth}"return request

5. 数据存储 pipelines.py

# pipelines.py
import json
import os
from feapder import Itemclass JobItem(Item):"""定义岗位信息结构"""def __init__(self):self.position = Noneself.company = Noneself.location = Noneself.salary = Noneclass JsonPipeline:"""将数据按照公司分类存储到 JSON 文件"""def open_spider(self, spider):# 创建存储目录self.base_path = spider.setting.get("DATA_PATH", "./data")os.makedirs(self.base_path, exist_ok=True)def process_item(self, item: JobItem, spider):# 按公司名称分类存储company = item.company or "unknown"file_path = os.path.join(self.base_path, f"{company}.json")# 追加写入with open(file_path, "a", encoding="utf-8") as f:f.write(json.dumps(dict(item), ensure_ascii=False) + "\n")return item

6. 爬虫脚本 spider.py

# spider.py
from feapder import Spider, Request
from pipelines import JobItem
import randomclass JobSpider(Spider):"""Feapder 爬虫:采集 51job 企业招聘信息"""def start_requests(self):# 入口 URL,搜索“Python 开发”岗位url = "https://search.51job.com/list/000000,000000,0000,00,9,99,Python开发,2,1.html"yield Request(url, callback=self.parse_list)def parse_list(self, request, response):# 解析列表页中的每个岗位链接for job in response.xpath("//div[@class='el']/p[@class='t1']/span/a"):job_url = job.xpath("./@href").extract_first()yield Request(job_url, callback=self.parse_detail)# 分页(示例:最多采集前 5 页)if int(request.url.split(",")[-1].split(".")[0]) < 5:next_page = int(request.url.split(",")[-1].split(".")[0]) + 1next_url = request.url.replace(f",{int(request.url.split(',')[-1].split('.')[0])}.html", f",{next_page}.html")yield Request(next_url, callback=self.parse_list)def parse_detail(self, request, response):"""解析岗位详情页"""item = JobItem()item.position = response.xpath("//h1/text()").extract_first().strip()     # 岗位名称item.company = response.xpath("//a[@class='catn']/text()").extract_first().strip()  # 公司名称item.location = response.xpath("//span[@class='lname']/text()").extract_first().strip()  # 工作地点item.salary = response.xpath("//span[@class='salary']/text()").extract_first().strip()   # 薪资待遇yield itemdef download_midware(self, request):"""在请求中注入 Cookie 与 User-Agent"""headers = {# 随机选择常见浏览器 UA"User-Agent": random.choice(["Mozilla/5.0 (Windows NT 10.0; Win64; x64)...","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)..."]),# 示例 Cookie,可根据需要替换"Cookie": "your_cookie_string_here"}request.request_kwargs.setdefault("headers", {}).update(headers)return requestif __name__ == "__main__":JobSpider(**{"project_name": "feapder_job_pipeline",# 可选:指定本地分布式队列# "redis_key": "job_spider_requests",# "processes": 4,}).start()

7. 运行与结果

python spider.py
  • 运行后,./data/ 目录下会出现以公司名命名的 JSON 文件,每行一条岗位信息。

五、扩展阅读

  • Feapder 官方文档:https://feapder.com/
  • Scrapy 官方文档(原理参考):https://docs.scrapy.org/
  • 爬虫代理使用指引:登录亿牛云官网查看“文档中心”
  • 同类案例:使用 Playwright 架构多语言爬虫(可对比)

通过本文演示,你已经掌握了如何用 Feapder 快速构建一个带有代理、Cookie、User-Agent 的企业级爬虫管道,并能将数据分类存储。接下来可以尝试接入数据库、监控告警,或将爬虫部署到 Kubernetes 集群,打造真正的生产级数据管道。

http://www.xdnf.cn/news/5993.html

相关文章:

  • [特殊字符] VMware虚拟机挂起后Docker容器MySQL无法连接的解决方案
  • Java类与对象的描述及内存原理
  • 激光打印机常见打印故障简单处理意见
  • WebPageTest 多地域测试
  • ElasticSearch深入解析(十一):分页和分批统计的三种实现
  • 【AI论文】健康的大型语言模型(LLMs)?——评估大型语言模型对英国政府公共健康信息的掌握程度
  • TypeScript 知识框架
  • Python之with语句
  • 高级 Java 锁技术:超越基本同步
  • 应用探析|千眼狼PIV测量系统在职业病防治中的应用
  • idea2021创建web项目及其整合tomcat
  • RuoYi-Cloud
  • CodeBuddy 中国版 Cursor 实战:Redis+MySQL双引擎驱动〈王者荣耀〉战区排行榜
  • 阳光学院【2020下】计算机网络原理-A卷-试卷-期末考试试卷
  • 中国区adsense接收pin码,身份验证和地址验证指南
  • AD Class创建与Class应用
  • 求由无穷串构成的二进制数的值
  • 初始“协议”
  • IPD流程实战:产品开发各阶段目标、关注点和交付
  • 基于概率论与数理统计的股市预测模型研究
  • WHAT - 《成为技术领导者》思考题(第九章)
  • 【漫话机器学习系列】256.用 k-NN 填补缺失值
  • LeetCode热题100--206.反转链表--简单
  • 捌拾肆- 量子傅里叶变换 (2)
  • 编译docker版openresty
  • MySQL——数据类型表的约束
  • 无线定位之四 SX1302 网关源码 thread_jit 线程详解
  • 道通EVO MAX系列无人机-支持二次开发
  • Springboot实现重试机制
  • 工具学习_VirusTotal使用