如何在Django中提取HTML标签属性值?IMDb新片抓取遇阻
嘿,我来帮你解决这个IMDb电影抓取的问题!看起来你已经离成功很近了,只是在属性提取和数据传递上有点小问题,咱们一步步来搞定它。
问题分析
你现在遇到的情况是,虽然用BeautifulSoup抓到了img标签列表,但在Django模板里无法正确提取属性,页面显示[, ,...]——这大概率是两个原因:要么是你直接把BeautifulSoup的Tag对象传给模板,Django模板对这类对象的属性访问逻辑和Python代码里不一样;要么是IMDb的页面结构已经更新,你原来用的选择器找不到有效元素了。
解决方案步骤
1. 先排查抓取逻辑(适配页面结构+优化请求)
首先,IMDb的页面结构经常更新,你原来用的"class": "poster shadowed"可能已经失效了。咱们先调整抓取代码,同时优化请求头避免被拦截:
def movies(request): import requests from bs4 import BeautifulSoup # 移除没用的urllib3导入 headers = requests.utils.default_headers() headers.update({ # 换成现代浏览器的User-Agent,避免被IMDb识别为爬虫 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' }) url = "https://www.imdb.com/movies-in-theaters/" req = requests.get(url, headers=headers) soup = BeautifulSoup(req.content, 'html.parser') # 适配当前IMDb页面的海报img选择器(当前用的是ipc-image类) movie_imgs = soup.find_all('img', class_='ipc-image') # 提前把需要的属性提取成普通字典列表,方便模板直接使用 movies_data = [] for img in movie_imgs: # 用get方法避免属性不存在时报错,提升健壮性 movies_data.append({ 'src': img.get('src'), 'alt': img.get('alt'), 'title': img.get('title') }) return render(request, 'movies.html', {'movies': movies_data})
2. 调整模板代码,直接访问字典属性
现在你传给模板的是普通的字典列表,模板里可以用简洁的点语法访问属性,还能直接把海报显示出来:
{% extends 'base.html' %} {% block content %} <table class="table table-hover table-bordered table-striped table-light"> <thead> <tr> <th scope="col">海报</th> <th scope="col">电影名称</th> <th scope="col">标题信息</th> </tr> </thead> <tbody> {% for m in movies %} <tr> <!-- 直接用src显示海报图片 --> <td><img src="{{ m.src }}" alt="{{ m.alt }}" style="width: 120px;"></td> <td>{{ m.alt }}</td> <td>{{ m.title|default:"无额外标题" }}</td> </tr> {% endfor %} </tbody> </table> <br/> <!-- 现在打印movies会显示清晰的字典列表,方便调试 --> {{ movies }} {% endblock %}
3. 关键注意点
- 选择器要实时验证:如果还是抓不到内容,右键点击IMDb页面的海报图片,选择「检查」,查看当前img标签的class或其他属性,再调整
find_all的参数。 - 提前转换数据结构:把BeautifulSoup的Tag对象转换成普通字典,不仅模板访问更简单,还能避免Django模板对第三方对象的兼容性问题。
- 容错处理:用
get方法提取属性,或者在模板里用|default过滤器,避免因为某个标签缺少属性导致页面报错。
内容的提问来源于stack exchange,提问作者Black Spanish




