Python-面试题(面试)
本文已加密,请输入密码继续阅读。
SessionPage 不执行 JavaScript,浏览器标签页读取渲染后的 DOM,WebPage / MixTab 能切换两种模式。两条路线都可以结构化解析 HTML。NoneElement 和浏览器开关差异。在线数据、布局和浏览器版本会变化,数字与输出不保证永久不变。AsyncWebCrawler.arun() 一次调用就把「起浏览器、等 JS、滚动、抽正文、转 markdown」全做完。inspect.signature 打全并逐个实测:BrowserConfig 44 个参数、CrawlerRunConfig 100 个参数、CrawlResult 29 个字段、CacheMode 5 种、深度抓取策略与过滤器链、四种结构化抽取、markdown 生成器与两种内容过滤器、会话与 cookie、反检测的三个适配器。cache_mode=BYPASS(不是「启用缓存」);它自带一个结构性反爬判据,小页面会被误判成「被拦截」(success=False 但正文其实抓到了,还会顺手打一行云广告);robots.txt 默认完全不遵守,check_robots_txt=True 才拒绝。cache_mode 与 session_id。get/post/Session/AsyncSession 都能用,卖点是一个 impersonate 参数就把 TLS 指纹、HTTP/2 帧、请求头顺序一起换成真实浏览器。Timeout、3 次 SSLError、1 次侥幸 200),所以抓在线站只能走默认栈,指纹相关的取证全部放在局域网靶站和本机 ClientHello 嗅探里做,每条结论都跟着逐字输出。BrowserType 枚举有 53 个成员但不含 chrome 这种别名(别名只在 BrowserTypeLiteral 的 63 个取值里);Session 默认 timeout=30 而不是 requests 的 None;files= 这个名字还在但一用就 NotImplementedError,上传要走 multipart=CurlMime。RequestQueue 与 Dataset 的本地存储、enqueue_links 四种策略、重试与错误处理、并发伸缩、代理与会话与指纹、robots.txt、停止与续爬。抓取对象沿用系列惯例:ssr1.scrape.center(服务端渲染)与 spa1.scrape.center(前端渲染),协议级用本机靶站。async def,本地存储是 storage/ 目录下的 JSON 文件,没有 Scrapy 的 Pipeline/中间件那套,也没有 feapder 的任务表与批次表。extras 决定你能用哪些类(裸装只有 HttpCrawler,报错原文见下一节),跑起来还有三个只有实测才知道的坑:默认队列会记住处理过的 URL,同一个 URL 第二次跑什么都不抓;enqueue_links(strategy=...) 只认四个小写值,写错不校验、把请求重试到失败;ConcurrencySettings(max_concurrency=1) 单独写会 ValueError,因为 desired_concurrency 默认是 10。ssr1.scrape.center 与 spa1.scrape.center,输出全部逐字贴出。redis<4.0.0,pip install --dry-run 显示会把已有的 redis 8.1.0 悄悄换成 3.5.3,一个 warning 都不给;Python 3.12 起标准库删掉 distutils,不装 setuptools 连 import feapder 都过不去。os._exit 硬退出,redis 里同时留下 score=300(待做)和 score=当前时间+600(取出中)两类任务,重启后打印「检查到有待做任务 9 条,不重下发新任务,将接着上回异常终止处继续抓取」。--ws-max-size)、测试(TestClient 与 httpx.AsyncClient 两条路)、部署(uvicorn / gunicorn / nginx / Docker,含代理头与并发上限的实测坑)。--limit-concurrency 是按「连接」算的,空闲的 keep-alive 连接也占额度——3 条闲置连接就能把第 4 个请求顶成 503,而且它是硬拒、不排队。Upgrade/Connection,实测配了是 101、没配是 404。OAuth2PasswordBearer 解 token → Security 查 scopes,每一步都在本机跑通并贴了实测输出。pwdlib,不再推荐 passlib:实测 passlib 1.7.4 配 bcrypt 5.0.0 直接 ValueError,一次哈希都做不出来;pwdlib 0.3.1 的 verify() 返回布尔值,还有 verify_and_update() 支持换算法。python-jose 实测也能跑,但已不是首选);decode() 必须显式传 algorithms,短密钥会告警,过期抛 ExpiredSignatureError。yield 依赖发 session。这篇以 MySQL + mysqlclient 为主路径,并用本机 WSL 的 PostgreSQL 18.6 做异步对照。sqlalchemy[asyncio] 这个 extra,不装就没有 greenlet,import 直接失败;expire_on_commit=True 在异步下会让 commit 后读属性抛 MissingGreenlet;session 依赖必须 try/finally,否则异常路径不收尾。select 1:同步 0.041s、异步串行 0.054s、异步并发 0.052s),异步的收益在慢数据库和高并发等待。