You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在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

火山引擎 最新活动