使用BeautifulSoup爬取Hotstar电影时,含连字符类名访问报错
你遇到的NameError: name 'cards' is not defined是因为对BeautifulSoup的点语法使用有误,我来帮你梳理下问题和解决方案:
错误原因
你代码里的container.div.hs-cards-directive.article.a这一行有个关键问题:hs-cards-directive并不是HTML标签的名称,它是Angular框架的自定义指令(通常作为元素属性存在,比如<div hs-cards-directive="...">),而BeautifulSoup的点语法只能用来访问标签名(比如div、article、a这类)。直接写hs-cards-directive会被Python当成一个未定义的变量,所以抛出了NameError。
修复方案
你需要根据HTML里的实际结构,用find()或CSS选择器来定位带有hs-cards-directive属性的元素,而不是用点语法。下面是两种可行的写法:
方法1:使用find()定位属性元素
假设你的HTML结构里,hs-cards-directive是某个元素的自定义属性,代码可以改成这样:
from bs4 import BeautifulSoup as soup page_soup = soup(open('hotstar.html'), 'html.parser') containers = page_soup.findAll("div", {"class":"col-xs-6 col-sm-4 col-md-3 col-lg-3 ng-scope"}) container = containers[0] # 定位带有hs-cards-directive属性的元素 card_container = container.div.find(attrs={"hs-cards-directive": True}) if card_container: # 继续查找article和a标签 article_tag = card_container.find("article") if article_tag: a_tag = article_tag.find("a") # 获取视频链接 video_link = a_tag.get("href") print(video_link)
如果hs-cards-directive是元素的class名称(比如<div class="hs-cards-directive">),则把find的参数改成class_="hs-cards-directive":
card_container = container.div.find(class_="hs-cards-directive")
方法2:使用CSS选择器(更简洁)
CSS选择器可以直接定位带有指定属性的元素,写法更紧凑:
from bs4 import BeautifulSoup as soup page_soup = soup(open('hotstar.html'), 'html.parser') containers = page_soup.findAll("div", {"class":"col-xs-6 col-sm-4 col-md-3 col-lg-3 ng-scope"}) container = containers[0] # 用CSS选择器直接定位到目标a标签 a_tag = container.select_one('div[hs-cards-directive] article a') if a_tag: video_link = a_tag["href"] print(video_link)
额外建议
在调试时,你可以先打印container.prettify(),查看这个容器内的具体HTML结构,确认标签层级和属性名称是否和你预期的一致,避免因为结构差异导致的查找失败。
内容的提问来源于stack exchange,提问作者Lancelot

