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

news2025/5/16 21:26:13

爬虫代理

本文将带你从零开始,借助 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 Request

class 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 中的 proxy
        request.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 Item

class JobItem(Item):
    """定义岗位信息结构"""
    def __init__(self):
        self.position = None
        self.company = None
        self.location = None
        self.salary = None

class 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 random

class 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]) + 1
            next_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 item

    def 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 request

if __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.coloradmin.cn/o/2377146.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从AlphaGo到ChatGPT:AI技术如何一步步改变世界?

从AlphaGo到ChatGPT&#xff1a;AI技术如何一步步改变世界&#xff1f; 这里给大家分享一个人工智能学习网站。点击跳转到网站。 https://www.captainbed.cn/ccc 前言 在科技发展的历史长河中&#xff0c;人工智能&#xff08;AI&#xff09;技术无疑是最为璀璨的明珠之一。从…

AI 编程革命:腾讯云 CodeBuddy 如何重塑开发效率?

引言 在传统开发流程中&#xff0c;开发者常需依赖 SDK 文档或反复调试来获取云资源信息。而随着 AI 技术爆发式发展&#xff0c;腾讯云推出的 CodeBuddy 正以对话式编程颠覆这一模式 —— 只需自然语言描述需求&#xff0c;即可直接生成可执行代码。作为腾讯混元大模型与 Dee…

星海智算云平台部署GPT-SoVITS模型教程

背景 随着 GPT-SoVITS 在 AI 语音合成领域的广泛应用&#xff0c;越来越多的个人和团队开始关注这项前沿技术。你是否也在思考&#xff0c;如何快速、高效地部署并体验这款强大的声音克隆模型&#xff1f;遗憾的是&#xff0c;许多本地部署方案不仅配置复杂&#xff0c;而且对…

15:00开始面试,15:06就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到4月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…

20250515通过以太网让VLC拉取视熙科技的机芯的rtsp视频流的步骤

20250515通过以太网让VLC拉取视熙科技的机芯的rtsp视频流的步骤 2025/5/15 20:26 缘起&#xff1a;荣品的PRO-RK3566适配视熙科技 的4800W的机芯。 1080p出图预览的时候没图了。 通过105的机芯出图确认 荣品的PRO-RK3566 的硬件正常。 然后要确认 视熙科技 的4800W的机芯是否出…

UE5.3 C++ 房屋管理系统(二)

三.当房屋生成成功&#xff0c;我们就需要把TMap里的数据存到数据库里。不然一点停止运行&#xff0c;就会所以数据都不见了。这里使用DataTable来存储。 1.DataTable是UE常用的表&#xff0c;虽然不是专门用来存档的&#xff0c;但也可以这么用。 DataTable表&#xff0c;实…

VSCode1.101.0便携版|中英文|编辑器|安装教程

软件介绍 Visual Studio Code是微软推出的一个强大的代码编辑器&#xff0c;功能强大&#xff0c;操作简单便捷&#xff0c;还有着良好的用户界面&#xff0c;设计得很人性化&#xff0c;旨在为所有开发者提供一款专注于代码本身的免费的编辑器。 软件安装 1、 下载安装包…

Linux系统发布.net core程序

前端 前端用的Vue3&#xff0c;发布的话需要Nginx下载安装Nginx 麒麟&#xff1a;这里我麒麟用的是桌面版&#xff0c;我直接把操作流程写在下面&#xff0c;写的比较简单&#xff0c;具体的可以具体搜这一块内容学习一下。打包vue程序&#xff0c;通过MobaXterm将打包后的程序…

极新携手火山引擎,共探AI时代生态共建的破局点与增长引擎

在生成式AI与行业大模型的双重驱动下&#xff0c;人工智能正以前所未有的速度重构互联网产业生态。从内容创作、用户交互到商业决策&#xff0c;AI技术渗透至产品研发、运营的全链条&#xff0c;推动效率跃升与创新模式变革。然而&#xff0c;面对AI技术迭代的爆发期&#xff0…

对比 HTTP-REST 与 gRPC:各自的优缺点以及适用的场景

文章目录 对比 HTTP-REST 与 gRPC&#xff1a;各自的优缺点以及适用的场景HTTP-REST 与 gRPC 的核心区别gRPC 的优缺点HTTP-REST 的优缺点适用场景 模糊点什么是 Protobuf&#xff1f;HTTP/2 会将 HTTP 消息拆分并封装为二进制帧&#xff0c;那还能过使用 HTTP/2 构建 RESTful …

Git - 1( 14000 字详解 )

一&#xff1a; Git 初识 1.1 提出问题 在工作或学习中&#xff0c;我们常常会面临文档管理的问题&#xff0c;尤其是在编写各种文档时。为了防止文档丢失或因更改失误而无法恢复&#xff0c;我们常常会创建多个版本的副本&#xff0c;例如&#xff1a;“报告-v1”、“报告-v…

TCPIP详解 卷1协议 九 广播和本地组播(IGMP 和 MLD)

9.1——广播和本地组播&#xff08;IGMP 和 MLD&#xff09; IPv4可以使用4种IP地址&#xff1a;单播&#xff08;unicast&#xff09;、任播&#xff08;anycast&#xff09;、组播&#xff08;multicast&#xff09;和广播&#xff08;broadcast&#xff09;。 IPv6可以使用…

16.1 - VDMA视频转发实验之TPG

文章目录 1 实验任务2 系统框图3 硬件设计3.1 IP核配置3.2 注意事项 4 软件设计4.1 注意事项4.2 工程源码4.2.1 main.c文件 1 实验任务 基于14.1&#xff0c;使用Xilinx TPG&#xff08;Test Pattern Generator&#xff09; IP提供视频源&#xff0c;将视频数据通过VDMA写入PS…

cocos creator 3.8 下的 2D 改动

在B站找到的系统性cocos视频教程,纯2D开发入门,链接如下: zzehz黑马程序员6天实战游戏开发微信小程序&#xff08;Cocos2d的升级版 CocosCreator JavaScript&#xff09;_哔哩哔哩_bilibili黑马程序员6天实战游戏开发微信小程序&#xff08;Cocos2d的升级版 CocosCreator Ja…

Unity光照笔记

问题 在做项目中遇到了播放中切换场景后地面阴影是纯黑的问题&#xff0c;不得不研究一下光照。先放出官方文档。 Lighting 窗口 - Unity 手册 播放中切换场景后地面阴影是纯黑 只有投到地面的阴影是纯黑的。且跳转到使用相同Terrain的场景没有问题。 相关文章&#xff1a…

嵌入式学习的第二十天-数据结构-调试+链表的一般操作

一、调试 1.一般调试 2.找段错误 二、链表的一般操作 1.单链表的修改 int ModifyLinkList(LinkList*ll,char*name,DATATYPE*data) {DATATYPE * tmp FindLinkList(ll, name);if(NULL tmp){return 1;}memcpy(tmp,data,sizeof(DATATYPE));return 0; } 2.单链表的销毁 int D…

家具制造行业的现状 质检LIMS如何赋能家具制造企业质检升级

在家具制造行业&#xff0c;从原木切割到成品出厂&#xff0c;质检环节贯穿始终 —— 木材含水率是否达标、板材甲醛释放量是否合规、涂层耐磨性能否通过标准…… 这些看似琐碎的检测项目&#xff0c;实则是企业把控产品品质、规避市场风险的核心关卡。传统人工质检模式在效率、…

idea整合maven环境配置

idea整合maven 提示&#xff1a;帮帮志会陆续更新非常多的IT技术知识&#xff0c;希望分享的内容对您有用。本章分享的是springboot的使用。前后每一小节的内容是存在的有&#xff1a;学习and理解的关联性。【帮帮志系列文章】&#xff1a;每个知识点&#xff0c;都是写出代码…

无偿帮写毕业论文(看不懂的可以私信博主)

以下教程教你如何利用相关网站和AI免费帮你写一个毕业论文。毕竟毕业论文只要过就行&#xff0c;脱产学习这么多年&#xff0c;终于熬出头了&#xff0c;完成毕设后有空就去多看看亲人好友&#xff0c;祝好&#xff01; 一、找一个论文模板 废话不多说&#xff0c;先上干货Ov…

小白成长之路-vim编辑

文章目录 Vim一、命令模式二、插入模式3.a:进入插入模式&#xff0c;在当前光标的后一个字符插入![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/fd293c3832ed49e2974abfbb63eeb5bb.png)4.o: 在当前光标的下一行插入5.i:在当前光标所在字符插入&#xff0c;返回命令模…