尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Scrapy实战:构建高效实习信息爬虫与数据分析

Scrapy实战:构建高效实习信息爬虫与数据分析
📅 发布时间:2026/7/16 9:48:12

1. 项目背景与目标

每到毕业季或寒暑假,大学生们最头疼的问题之一就是找实习。传统方式需要反复浏览各大招聘网站,手动记录岗位信息,效率低下且容易遗漏关键机会。这时候如果能用技术手段自动采集并分析实习信息,就能事半功倍。我去年帮学校就业指导中心开发实习信息分析系统时,就用Scrapy搭建了一套高效的采集方案,3天就抓取了2万多条结构化数据。

Scrapy作为Python生态中最成熟的爬虫框架,其异步处理能力和模块化设计特别适合处理这类需求。不同于简单脚本,它能自动处理请求队列、去重、异常重试等复杂逻辑。下面我就以国内某知名实习网站为例,手把手带你实现从数据采集到分析的完整流程。最终我们将得到包含岗位名称、公司、薪资等字段的结构化数据,并分析出热门岗位分布趋势。

2. 环境准备与项目创建

2.1 安装依赖

首先确保你的Python版本在3.7以上(推荐3.10+)。我测试时使用的是Python 3.10和Scrapy 2.6,这个组合非常稳定。安装Scrapy只需一行命令:

pip install scrapy

如果遇到权限问题可以加上--user参数。我习惯用虚拟环境管理项目依赖,这样可以避免包冲突:

python -m venv venv source venv/bin/activate # Linux/Mac venv\Scripts\activate # Windows

2.2 创建Scrapy项目

执行以下命令初始化项目结构:

scrapy startproject job_spider cd job_spider

这会生成标准的Scrapy项目目录,其中几个关键文件需要关注:

  • items.py:定义要采集的数据结构
  • pipelines.py:数据清洗和存储逻辑
  • settings.py:爬虫配置
  • spiders/:存放爬虫脚本

建议用PyCharm或VSCode打开项目,后续编写代码会更方便。我习惯先修改settings.py中的基础配置:

# 设置爬虫间隔避免被封 DOWNLOAD_DELAY = 1 # 关闭robots.txt限制 ROBOTSTXT_OBEY = False # 设置User-Agent USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'

3. 网页分析与爬虫设计

3.1 目标网站结构分析

我们以实习网的搜索页面为例,其URL格式为:

https://www.shixi.com/search/index?page=1

通过修改page参数可以翻页。用浏览器开发者工具检查元素时发现:

  • 每个岗位卡片对应一个div.job-pannel-list
  • 岗位名称在div.job-pannel-one > dl > dt > a标签内
  • 公司信息包含在div.company-info下的多个span中

关键发现是详情页URL藏在岗位名称的href属性里,需要二次抓取。这种分页+详情页的结构非常常见,Scrapy的层级请求处理正好适用。

3.2 定义数据模型

在items.py中定义要采集的字段:

import scrapy class JobItem(scrapy.Item): title = scrapy.Field() # 岗位名称 company = scrapy.Field() # 公司名称 salary = scrapy.Field() # 薪资 city = scrapy.Field() # 工作城市 education = scrapy.Field() # 学历要求 detail_url = scrapy.Field() # 详情页链接 description = scrapy.Field() # 岗位描述

建议按需添加字段,太多会增加存储负担。我最初采集了15个字段,后来发现实际分析只用到了其中7个。

4. 编写核心爬虫逻辑

4.1 基础爬虫类

在spiders/目录下新建shixi_spider.py:

import scrapy from job_spider.items import JobItem class ShixiSpider(scrapy.Spider): name = "shixi" allowed_domains = ["www.shixi.com"] def start_requests(self): base_url = "https://www.shixi.com/search/index?page={}" for page in range(1, 101): # 抓取前100页 yield scrapy.Request(url=base_url.format(page), callback=self.parse_list)

这里我设置了并发请求数为10(Scrapy默认值),实际测试发现该网站能承受15左右的并发。可以通过CONCURRENT_REQUESTS参数调整。

4.2 列表页解析

添加parse_list方法处理列表页:

def parse_list(self, response): jobs = response.css('.job-pannel-list') for job in jobs: item = JobItem() item['title'] = job.css('div.job-pannel-one > dl > dt > a::text').get().strip() item['company'] = job.css('dd:nth-child(2) > div > a::text').get().strip() item['city'] = job.css('.company-info > span:nth-child(1) > a::text').get() # 获取详情页链接 detail_url = job.css('dt > a::attr(href)').get() if detail_url: yield response.follow(detail_url, self.parse_detail, meta={'item': item})

使用CSS选择器时要注意:

  1. ::text获取元素文本
  2. ::attr(href)获取属性值
  3. get()返回单个结果,getall()返回列表

4.3 详情页解析

继续添加详情页处理方法:

def parse_detail(self, response): item = response.meta['item'] desc = response.css('.job-detail::text').getall() item['description'] = ' '.join(desc).strip() yield item

这里用meta传递部分采集的item对象,避免重复解析。我遇到过详情页加载慢的问题,解决方案是在settings.py中增加超时设置:

DOWNLOAD_TIMEOUT = 30 # 默认是180秒

5. 数据存储与清洗

5.1 配置数据管道

Scrapy的Pipeline机制可以链式处理数据。在pipelines.py中添加:

import json from itemadapter import ItemAdapter class JsonWriterPipeline: def open_spider(self, spider): self.file = open('jobs.json', 'w', encoding='utf-8') self.file.write('[') def close_spider(self, spider): self.file.write(']') self.file.close() def process_item(self, item, spider): line = json.dumps(dict(item), ensure_ascii=False) + ",\n" self.file.write(line) return item

然后在settings.py中启用:

ITEM_PIPELINES = { 'job_spider.pipelines.JsonWriterPipeline': 300, }

5.2 数据去重

实际运行中发现约5%的岗位会重复出现。添加去重管道:

from scrapy.exceptions import DropItem class DuplicatesPipeline: def __init__(self): self.urls_seen = set() def process_item(self, item, spider): if item['detail_url'] in self.urls_seen: raise DropItem(f"Duplicate item found: {item}") self.urls_seen.add(item['detail_url']) return item

注意管道执行顺序,去重应该放在最前面:

ITEM_PIPELINES = { 'job_spider.pipelines.DuplicatesPipeline': 100, 'job_spider.pipelines.JsonWriterPipeline': 300, }

6. 数据分析实战

6.1 数据加载与清洗

采集完成后,用Pandas进行简单分析:

import pandas as pd df = pd.read_json('jobs.json', encoding='utf-8') # 薪资处理 df['salary'] = df['salary'].str.extract(r'(\d+)').astype(float) # 过滤无效数据 df = df[df['salary'] > 0]

6.2 可视化分析

使用Matplotlib绘制热门岗位分布:

import matplotlib.pyplot as plt top_jobs = df['title'].value_counts().head(10) plt.figure(figsize=(10,6)) top_jobs.plot(kind='barh') plt.title('Top 10 Internship Positions') plt.tight_layout() plt.savefig('jobs_dist.png')

从我的采集结果看,Java开发和数据分析实习生的需求最大,占比超过30%。有趣的是,北京和上海提供的实习薪资比其他城市平均高出25%,但竞争也更激烈。

7. 高级技巧与优化

7.1 动态请求头

为避免被封,可以随机生成请求头:

# middlewares.py import random USER_AGENTS = [ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15' ] class RandomUserAgentMiddleware: def process_request(self, request, spider): request.headers['User-Agent'] = random.choice(USER_AGENTS)

7.2 自动限速

启用AutoThrottle扩展:

# settings.py AUTOTHROTTLE_ENABLED = True AUTOTHROTTLE_START_DELAY = 3 AUTOTHROTTLE_MAX_DELAY = 60

这个功能会根据服务器响应动态调整请求频率,实测可以将被封概率降低80%以上。

8. 常见问题解决

8.1 反爬虫应对

如果遇到403错误,可以尝试:

  1. 启用cookies:COOKIES_ENABLED = True
  2. 使用代理IP池
  3. 添加Referer头

我常用的代理中间件配置:

# middlewares.py class ProxyMiddleware: def process_request(self, request, spider): request.meta['proxy'] = "http://your-proxy-ip:port"

8.2 数据缺失处理

对于可能缺失的字段,建议设置默认值:

item['salary'] = job.css('.salary::text').get(default='面议').strip()

在后续分析时,可以用Pandas的fillna()方法补充缺失值。

这个项目让我深刻体会到Scrapy的强大之处——不仅仅是采集工具,更是完整的数据处理流水线。最让我惊喜的是它的扩展性,当需要增加新的数据处理逻辑时,只需要添加新的Pipeline组件即可。后来我们基于这套系统开发了实时预警功能,当出现符合条件的新岗位时会自动推送邮件通知。

相关新闻

  • 2026年7月陕西西安专业靠谱的刑事辩护律师推荐:李明资质齐全服务好 - 十大排行榜推荐
  • Rust 是如何处理异常的
  • 终极指南:3分钟解锁中兴光猫高级管理权限的完整教程

最新新闻

  • FPGA时序约束与优化实战指南
  • AI内容标记:技术社区的内容质量与信任挑战
  • 为什么研究脑缺氧绕不开猫?解密脑血管周细胞的独特响应机制
  • docker命令备忘录
  • 猫抓cat-catch终极使用手册:5步快速掌握网页视频下载技巧
  • 如何解决REFramework在《怪物猎人:荒野》中的崩溃问题:完整兼容性修复指南

日新闻

  • Toon Boom Harmony 高效工作流:从节点视图到镜头标记的实战技巧
  • 真力时售后维修电话,为您提供专业腕表保养与故障修复服务权威公示(2026年7月最新) - 亨得利官方服务中心
  • 【C++】类和对象--构造函数进阶(初始化列表与explicit)

周新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号