不推荐在 Django 视图中直接调用 requests + BeautifulSoup,因其会阻塞同步 Web 服务器线程,导致超时、白屏、CPU 打满等问题;应改用管理命令定时执行,并注意超时设置、异常捕获、HTML 清洗与解析健壮性。

在 Django 视图里直接调用 requests + BeautifulSoup 会出什么问题
不推荐在视图函数或类中直接写爬虫逻辑,尤其当请求目标响应慢、超时或返回异常时,会阻塞整个 HTTP 请求线程,导致用户看到白屏或 504。Django 默认是同步 Web 服务器(如 runserver 或 uWSGI 同步模式),没有自动异步调度能力。
常见错误现象:ConnectionTimeout、ReadTimeout、视图卡死几秒后抛 requests.exceptions.Timeout、并发稍高就 CPU 打满。
- 务必设置
timeout参数,例如requests.get(url, timeout=(3, 7))(3 秒连,7 秒读) - 避免在
get_queryset()或模板{{ object.xxx }}中隐式触发请求——这会让 ORM 查询和网络 I/O 混在一起,调试困难 - 不要把
BeautifulSoup(html, 'html.parser')放在循环里反复初始化,解析器对象可复用
manage.py 命令比视图更适合做定时采集
把爬取逻辑拆进自定义管理命令,既解耦请求生命周期,又方便配合 crontab 或 systemd timer 定期执行。它天然适合“获取→清洗→存库”这种单向流程。
使用场景:每天凌晨抓一次天气数据存进 WeatherReport 模型;每周同步一次商品价格到本地缓存表。
- 命令路径必须是
myapp/management/commands/fetch_prices.py,文件名即命令名 - 在
handle(self, *args, **options)里写主逻辑,别忘了捕获requests.RequestException和AttributeError(bs4找不到标签时最常抛这个) - 大量数据入库用
MyModel.objects.bulk_create([...], ignore_conflicts=True),比循环save()快一个数量级
BeautifulSoup 解析时 selector 写错的三个高频坑
不是所有网页都老老实实用 class/id,更常见的问题是:HTML 是 JS 渲染的(你 requests 拿到的是空壳)、编码没指定对、或者标签嵌套比你想象的深。
典型错误现象:find('div', class_='price') → None;select('ul li a') 返回空列表;中文乱码成 \xe4\xbb\xa3\xe7\x90\…。
- 先确认响应编码:
r = requests.get(url); r.encoding = r.apparent_encoding,再传给BeautifulSoup(r.text, ...) - 别迷信
class_='xxx',试试select('.xxx')或正则:find_all('div', class_=re.compile(r'price|cost')) - 检查是否为动态渲染:用
curl -s URL | head -20看原始 HTML 是否含目标内容,不含就说明得换方案(比如 Playwright)
Django 模型字段怎么存 HTML 片段或富文本
如果目标是存原始 HTML(比如文章正文、带样式的商品描述),别用 TextField 就完事——XSS 风险、数据库膨胀、后续无法索引关键词。
性能影响:未过滤的 HTML 直接入库,可能让 SELECT * 变慢;没 strip 的空白字符会让搜索失效。
- 入库前用
bleach.clean(html, tags=['p', 'br', 'strong'], strip=True)过滤危险标签 - 需要全文检索?加个
SearchVectorField并在save()里更新:self.search_vector = SearchVector('cleaned_content') - 纯展示用,且结构固定,考虑用
JSONField存解析后的关键字段(如{'title': ..., 'price': ..., 'img_url': ...}),比存整页 HTML 更可靠
事情说清了就结束。真正麻烦的从来不是怎么写那几行 requests.get 和 bs4.find,而是谁来保活、谁来重试、谁来记录失败 URL、下游系统断了要不要告警——这些不在 BeautifulSoup 文档里。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











