新闻详情

新闻详情

首页 / 资讯中心 / 详情

Python后端爬虫专题17:让Spider交付一份能被后端读取的数据——完成JobSpider与JSONL输出

发布时间:2026/10/1 2:43:09来源:尧图网络
Python后端爬虫专题17:让Spider交付一份能被后端读取的数据——完成JobSpider与JSONL输出
Python后端爬虫专题17让Spider交付一份能被后端读取的数据——完成JobSpider与JSONL输出上一篇练习完整答案完整数据流是start_urls被转换为 RequestEngine 交给 SchedulerScheduler 去重和排队Engine 取出后经下载中间件送到 DownloaderResponse 逆向回 EngineEngine 调用 Spiderparse它产生详情/分页 Request 再进 Scheduler详情响应触发parse_jobdict 进入 Item Pipeline 和 Feed Exporter。Stats Collector 在各阶段接收信号并累计统计。callbackself.parse_job传递可调用对象等响应回来由 Engine 注入 responsecallbackself.parse_job()会在构造 Request 当下执行由于缺少 response 立即 TypeError即便勉强传值传入 callback 的也会是调用结果而非函数。重复链接首先经过parse_listing的列表收集当前解析器会按 DOM 出现顺序给出 URLScrapy Request 进入 Scheduler 后由请求指纹去重。跨任务再次运行时 Scheduler 去重历史未必保留所以数据库(tenant_id, source_url)唯一约束仍承担最终幂等。可以用下面命令观察单测构造出的请求.\.venv\Scripts\python.exe-m pytest tests\test_framework_adapters.py::test_scrapy_spider_emits_detail_and_pagination_requests-q先定义交付物再运行 Spider一个 Spider “能跑”并不等于能交付。JobRadar 需要逐行 JSON每行独立解析、UTF-8、不转义中文、日期是 ISO 字符串、字段与JobItem一致。这样的文件可以流式导入数据库也能在后续交给数据分析或 RAG不必一次把整个数组载入内存。详情回调因此不返回 HTML 片段也不返回 Scrapy Selector而是经过parse_detail和 Pydantic 的 dict。输入是一个详情 Response输出是零或一个业务 item页面字段缺失时明确失败不生成半条职位。用本地 TargetLab 实际跑一次先在一个终端启动受控目标cd project.\.venv\Scripts\python.exe-m uvicorn targetlab.app:app--host 127.0.0.1--port 8011再开另一个终端执行 Spider。-O表示覆盖输出如果用-o追加多次练习会把旧行混进新结果cd project.\.venv\Scripts\scrapy.exe runspider src\jobradar\scrapy_spider.py -a seed_urlhttp://127.0.0.1:8011/jobs?page1 -Odata\scrapy-jobs.jsonl:jsonlines -s LOG_LEVELINFO命令行运行单文件 Spider 时Python 包导入路径必须来自已安装的 editable 项目这也是前面要求pip install -e的原因。若只双击脚本Scrapy Engine 并不会自动启动。输出文件应有三行。用 Python 而不是肉眼验证.\.venv\Scripts\python.exe-cimport json,pathlib; ppathlib.Path(data/scrapy-jobs.jsonl); rows[json.loads(x) for x in p.read_text(encodingutf-8).splitlines()]; print(len(rows), rows[0][title], rows[0][published_at])期望类似3 Python 后端工程师 2026-09-01。这一步同时抓住空文件、中文编码、日期不可序列化和字段名漂移。课程检查点则专门验证 callback 输出.\.venv\Scripts\python.exe-m pytest tests\test_framework_adapters.py::test_scrapy_detail_callback_yields_json_serializable_item-q为什么不在 parse_job 直接写数据库回调直接创建 Session、commit 会把调度逻辑与事务绑死测试需要真实数据库而且高并发时容易耗尽连接。更合适的方案有两种小型任务让 Item Pipeline 持有一次 Spider 生命周期内的资源与现有 JobRadar 集成时让 item 进入清洗/持久化适配层调用JobRepository.upsert统一 tenant 与幂等规则。无论选择哪种Spider 都应该产出稳定合同而不是同时负责登录、解析、SQL 和告警。框架回调越胖失败后越难知道应该重试网络还是回滚事务。Feed 输出并不是数据库JSONL 是一次运行的工件不支持并发唯一约束、租户查询或任务状态。它适合抽样、交接和离线重放却不能替代 PostgreSQL。反过来数据库也不适合作为源页面证据所以第 12 篇保存原始快照。项目真实存在三个层次原始 HTML、经过校验的 JobItem、可查询的 JobRecord。处理坏页面时要看统计若详情解析抛异常Scrapy 日志会出现 spider error成功 item 数小于发现请求数。不要看到进程退出码为 0 就宣布全量成功至少查看item_scraped_count、响应状态分布、retry/count、downloader/exception_count 和 finish_reason。第 18 篇会把这些数字变成运行判断。本篇完整 JobSpider与上一篇使用同一源码但阅读焦点改变这次关注parse_job的输出合同以及custom_settings对导出的影响。重复展示完整模块是为了让单篇发布时读者不必跳回旧文拼代码。让 Scrapy 的调度能力复用 JobRadar 已验证的解析合同。fromcollections.abcimportIterablefromurllib.parseimporturlsplitimportscrapyfromscrapy.httpimportResponsefromjobradar.parsingimportparse_detail,parse_listingclassJobSpider(scrapy.Spider):采集 TargetLab 列表与详情item 字段与 JobItem 完全一致。namejobradar_jobscustom_settings{ROBOTSTXT_OBEY:True,AUTOTHROTTLE_ENABLED:True,CONCURRENT_REQUESTS_PER_DOMAIN:2,DOWNLOAD_TIMEOUT:10,RETRY_HTTP_CODES:[429,500,502,503,504],FEED_EXPORT_ENCODING:utf-8,}def__init__(self,seed_url:str,*args:object,**kwargs:object)-None:super().__init__(*args,**kwargs)partsurlsplit(seed_url)ifparts.schemenotin{http,https}ornotparts.hostname:raiseValueError(seed_url must be an absolute HTTP(S) URL)self.start_urls[seed_url]self.allowed_domains[parts.hostname]defparse(self,response:Response,**kwargs:object)-Iterable[scrapy.Request]:listingparse_listing(response.text,response.url)fordetail_urlinlisting.detail_urls:yieldscrapy.Request(detail_url,callbackself.parse_job)iflisting.next_url:yieldscrapy.Request(listing.next_url,callbackself.parse)defparse_job(self,response:Response)-Iterable[dict[str,object]]:itemparse_detail(response.text,response.url)yielditem.model_dump(modejson)本篇课后练习实际运行 TargetLab 与 Spider把三行 JSONL 逐行读回并写出完整校验脚本字段集合一致、日期是字符串、source_url 唯一。比较-o与-O解释为什么定时全量导出通常选择覆盖而事件流才选择追加。故意使用job-detail-missing-title.html调parse_job记录异常字段名并说明为什么不能返回 title 为空的 dict。下一篇从一次“进程成功但数据少了”的故障开始学习 Scrapy 统计和节流。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

MCP协议实现AI驱动的Excel智能自动化 2026/10/1 5:20:50

MCP协议实现AI驱动的Excel智能自动化

1. 什么是MCP?它和Excel自动化到底有什么关系?“开发自己的第一个MCP——用AI智能重构Excel处理工作流”,这个标题里藏着三个关键认知断层:MCP不是某个现成软件,Excel自动化也不再是宏或VBA的代名词,而“AI…

阅读更多 →
从零破解Windows CrackMe:静态分析与动态调试实战 2026/10/1 5:20:50

从零破解Windows CrackMe:静态分析与动态调试实战

作为一个常年在BUUCTF上刷REVERSE题的老人,我对crackMe这种题感情很复杂:说难不难,说简单也不简单。BUUCTF上这类题收录了不少,特点就是给你一个Windows小exe,让你输入用户名和序列号,通过校验就算破解成功…

阅读更多 →
AnythingLLM实战:从私有化ChatGPT到local-first AI Agent工作区 2026/10/1 5:20:50

AnythingLLM实战:从私有化ChatGPT到local-first AI Agent工作区

我最早注意到 AnythingLLM,是在一个吐槽帖里看到有人把它叫“给不想买会员的人准备的 ChatGPT 套壳”。这个评价不能说全错,但只说对了一小半。我当时正好在帮团队折腾内部知识库的事,拖了好几个方案都没跑通,抱着“再试一个开源项…

阅读更多 →
鸭子数据集VOC和YOLO格式目标标注348张:直接用于目标检测训练 2026/10/1 5:20:44

鸭子数据集VOC和YOLO格式目标标注348张:直接用于目标检测训练

简介:这份鸭子目标检测数据集面向计算机视觉入门者、算法工程师及需要扩充训练样本的研究人员,用于鸭子识别与检测模型的训练与验证。资源同时提供VOC与YOLO两种标注格式,可直接对接主流检测框架,省去格式转换环节。压缩包共1039个…

阅读更多 →
WeKnora 私有化知识库部署实战:从 RAG 原理到调优避坑指南 2026/10/1 5:20:43

WeKnora 私有化知识库部署实战:从 RAG 原理到调优避坑指南

上次在技术群里看到有人问:有没有一套现成的 AI 知识库方案,能把公司几千份文档喂给大模型,让员工直接用对话的方式查资料?我当时第一反应就是推荐 WeKnora。这个项目是腾讯微信团队开源出来的 AI 知识库解决方案,我前…

阅读更多 →
Godot中100%复刻ALS:第三人称角色运动系统实战拆解 2026/10/1 5:20:43

Godot中100%复刻ALS:第三人称角色运动系统实战拆解

1. 这个项目到底在做什么第一次看到“在Godot中实现ALS的100%复刻”这个标题,很多没接触过虚幻引擎动画系统的朋友可能会一脸懵。ALS是Advanced Locomotion System的缩写,最早是虚幻引擎社区里一套非常有名的第三人称角色运动动画框架,作者是…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉