一、考察基础编程能力
1、请简述 Requests + BeautifulSoup 和 Scrapy 的区别,什么场景下选哪个?
- Requests+BS4 轻量灵活,适合一次性脚本、小规模数据抓取、接口请求场景;
- Scrapy 是异步框架,内置 Item Pipeline、中间件、去重等机制,适合大规模、持续化的爬取任务。
- 需要高并发、多站点、规范化数据流转时优先选 Scrapy;需要快速验证或对接 API 时选 Requests。
2、如何用 Python 发一个带 Cookie 和自定义 Header 的 POST 请求?写出关键代码。
- 使用
requests.Session(),在 session 上设置headers和cookies,然后调用session.post(url, json=payload)。关键在于复用 Session 对象以自动维持 Cookie 状态,而非每次手动传递。
3、XPath 和 CSS 选择器各有什么优缺点?你平时倾向用哪个?
- XPath 支持父节点回溯(
parent::)、文本内容匹配(contains(text(),'xxx'))、轴操作,适合复杂定位; - CSS 选择器语法更简洁,浏览器原生支持,调试方便。
- 日常推荐 CSS,结构复杂或需要向上查找时用 XPath。
4、如何对采集到的数据进行去重?有哪些常见方案?
- 数据库层:建唯一索引,INSERT IGNORE 或 ON CONFLICT DO NOTHING;
- 内存层:Python set 存 URL/ID 哈希,适合小批量;
- Redis 层:使用 SADD 存 URL 指纹(Scrapy 内置 RFPDupeFilter 即此方案);
- 布隆过滤器:大规模场景用
scrapy-redis+ Bloomfilter,内存占用极低但有误判。
二、反爬处理
1、网站常见的反爬机制有哪些?你分别是如何应对的?
- UA 检测:轮换 User-Agent 列表(fake-useragent 库);
- IP 限频/封禁:代理池(芝麻/快代理/自建)+ 限速 + 随机延迟;
- Cookie/Session 失效:自动登录续期 + Session 复用;
- Referer/Origin 校验:在 Header 中伪造合理的 Referer;
- JS 动态渲染:Selenium/Playwright 无头浏览器;
- 验证码:打码平台(2Captcha、超级鹰)或 AI 识别;
- 设备指纹/TLS 指纹:使用 curl_cffi / tls-client 绕过 TLS 识别。
2、代理池如何维护?如何检测代理是否有效?
- 定期向目标网站或
httpbin.org/ip发送心跳请求,统计响应时间和成功率; - 对失败次数超过阈值的代理自动踢出;
- 按响应速度分级(高/中/低质量),优先使用高质量代理;
- 若使用开源代理池(ProxyPool),结合 Redis 存储状态和调度器定时验证。
3、遇到图片验证码和滑块验证码,你有哪些解决思路?
- 图片验证码:① 打码平台(付费,准确率高);② 本地 OCR(tesseract + 预处理);③ 深度学习模型(CNN 识别)。
- 滑块验证码:① 分析轨迹接口,模拟带加速度的人类滑动轨迹;② 用 Playwright/Selenium 获取缺口图,通过图像差异计算偏移量,再构造带物理特征的轨迹数组;③ 若是 CAPTCHA 服务商(如极验),可尝试逆向其 JS 算法。
4、如果某页面接口参数被加密(如 sign/token),你怎么分析和还原?
- Chrome DevTools Network 面板抓包,定位参数的请求来源;
- 搜索 JS 文件中的参数名,找到生成逻辑(可用 Source 面板的全局搜索);
- 对混淆代码使用 js-beautify 格式化,或直接在断点处观察变量;
- 用 Python 复现加密逻辑(如 HMAC-SHA256、MD5 拼接盐值等);
- 复杂情况可用 Node.js 执行原始 JS 逻辑,通过 subprocess 调用;
- 终极方案:execjs / PyExecJS 直接执行浏览器 JS。
三、动态页面与工具使用
1、什么是动态渲染页面?如何判断一个页面是否需要用无头浏览器?
- 动态渲染页面是指数据由 JavaScript 在客户端运行后才生成到 DOM 的页面。
- 判断方法:① 用
requests直接获取响应,与浏览器中看到的内容比对;② 若响应 HTML 中含目标数据则无需浏览器;③ 若响应为空或仅含框架代码,则为动态渲染,需 Selenium/Playwright;④ 可用 Chrome 右键"查看网页源代码"(非 F12)------ 源代码无数据即为动态。
2、Playwright 和 Selenium 的主要区别是什么?你会如何选择?
- Playwright 更现代:原生支持异步(async/await)、多浏览器(Chromium/Firefox/WebKit)、自动等待元素、请求拦截更灵活,且不依赖 WebDriver 协议,稳定性更好;
- Selenium 生态成熟、文档多,但配置驱动版本麻烦,同步为主。
- 新项目推荐 Playwright,团队已有 Selenium 基础则继续用 Selenium。
3、如何用 Playwright 拦截并修改网络请求?举一个实际使用场景。
- 使用
page.route()注册拦截器,可对匹配 URL 的请求执行route.fulfill()(返回自定义响应)、route.continue_()(透传)或route.abort()(拦截)。 - 实际场景:① 屏蔽图片/广告加载以加速采集;② 拦截 XHR 直接获取 JSON 数据,避免解析 DOM;③ 注入自定义 Cookie 或 Header 绕过鉴权。
四、数据处理与存储
1、采集到的原始数据通常有哪些脏数据问题?你如何清洗?
- 常见问题:① 多余空白/换行(
strip()+ 正则);② 编码错误(chardet检测 +decode);③ 字段缺失(默认值填充或标记 NULL);④ 类型不一致(日期格式统一、数值字符串转换);⑤ 重复数据(唯一键去重);⑥ 特殊字符/HTML 实体(html.unescape());⑦ 空列表/嵌套结构展开(pandasexplode或递归提取)。
2、采集数据存入数据库时,如何保证不重复插入且效率高?
- 在目标字段上建唯一索引;
- 使用
INSERT IGNORE(MySQL)或INSERT ... ON CONFLICT DO NOTHING(PostgreSQL); - 批量插入(
executemany/ bulk_write),减少网络往返; - 先查 Redis 指纹集合判断是否采集过,命中则跳过,不命中再写库;
- 对高频写入场景,先写消息队列(Kafka/Redis Queue),异步批量落库。
3、如果要对接数据标注小组,你会如何设计数据交付的格式和流程?
- 明确字段规范(必填/可选、数据类型、枚举值)并输出字段说明文档;
- 交付格式通常为 JSON Lines 或带表头的 CSV/Excel,字段名用英文下划线命名;
- 每批数据附带采集时间、来源 URL、数据条数等 metadata;
- 建立验收标准:完整度(非空率)、准确度抽样核查比例;
- 建立反馈通道,标注组发现问题能回传到采集侧并触发重采。
五、系统设计与工程规范
1、如何设计一个可扩展、易维护的爬虫项目结构?
- 推荐分层结构:
spiders/(各站点采集逻辑)、parsers/(解析规则)、pipelines/(清洗+存储)、middlewares/(代理/UA/重试)、config/(站点配置化,避免硬编码)、utils/(工具函数)。 - 配置与代码分离,每个站点的 URL pattern、字段映射写在 YAML/JSON 中,新增站点只需加配置文件,不动核心代码。
2、爬虫运行时如何做监控和异常告警?
- 记录每次请求的状态码分布、成功率、响应时间到日志;
- 对连续失败(如 5xx 比例超阈值)触发邮件/企微/钉钉告警;
- 统计单位时间采集条数,低于基线时告警(可能被封或页面结构变更);
- 使用 Prometheus + Grafana 或简单地把指标写 Redis,定时脚本检查并推送。
3、你如何保证爬虫的采集频率不影响目标网站的正常运行(合规与礼貌爬取)?
- 遵守 robots.txt 协议,不采集明确禁止的路径;
- 设置合理的请求间隔(1~5 秒随机延迟);
- 限制并发数,避免瞬间高并发;
- 选择非业务高峰时段采集;
- 设置真实的 User-Agent,不伪装成其他主流爬虫;⑥ 若数据量大且对方有 API,优先使用官方 API。
六、AI辅助采集
1、你如何利用大模型辅助爬虫开发?有哪些具体落地场景?
- 代码生成:用 AI Coding 工具(Copilot/Claude Code)快速生成解析模板,减少重复代码;
- 页面自动解析:将 HTML 片段喂给 LLM,让其提取结构化字段,适合页面结构多变或无规律的场景;
- 选择器生成:告诉模型"帮我写一个提取这段 HTML 中商品名称的 XPath";
- 异常诊断:把报错日志和响应贴给模型分析;
- JS 逆向辅助:将混淆代码贴给模型解读加密逻辑。
2、什么是 RAG?在数据采集场景下它能发挥什么作用?
- RAG(Retrieval-Augmented Generation)是将检索到的外部文档作为上下文喂给大模型的技术。在采集场景中:① 可将采集到的非结构化文本(新闻、报告)通过向量检索+LLM 提取成结构化数据;② 构建知识库,让模型回答"某网站的接口规律是什么";③ 辅助构建自动化解析流水线,对新页面自动推断字段映射。
3、如果让你设计一个"给定 URL,自动输出结构化数据"的 AI 采集方案,你会怎么做?
- 用 Playwright 渲染页面,获取完整 DOM 和截图;
- 对 HTML 做精简(去脚本/样式,只保留可见文本和关键属性);
- 将精简 HTML 送入 LLM,提示词中明确目标字段和输出 JSON Schema;
- 解析 LLM 输出,校验必填字段和类型;
- 对置信度低的字段标记人工审核;
- 迭代优化提示词,积累不同站点的提取模板。技术栈参考:Playwright + GPT-4o/Claude + pydantic 校验 + 结果入库。