如何提取bs4.element.Tag的首个元素?以及如何从指定span标签中提取opiniones前的数字?
解决你的两个BeautifulSoup问题
问题1:提取bs4.element.Tag对象的第一个元素
对于bs4.element.Tag类型的对象,你可以通过它的.contents属性获取所有子节点的列表,直接取索引[0]就能拿到第一个元素——就像你代码里已经用到的res_name.find('a').contents[0]一样。
需要注意的是:.contents会包含所有类型的子节点(比如文本节点、注释节点、嵌套的Tag节点),如果第一个节点不是你需要的内容,可能需要先过滤掉无关节点(比如注释、空白文本)。不过在你当前的场景里,目标内容刚好是Tag的第一个子节点,这个方法完全适用。
问题2:提取"opiniones"前的数字
看你给出的输出,number_of_reviews对应的是<span>标签对象,内部结构是数字<!-- --> opiniones。这里有几种简单可靠的方法提取数字:
方法1:直接取第一个文本子节点
数字是<span>的第一个子节点,直接用.contents[0]就能精准拿到:
dataframe["number_of_reviews"] = res_stats.find("span", attrs={"class": "NoCoR"}).contents[0]
这个方法最直接高效,完全匹配你当前的HTML结构。
方法2:提取完整文本后分割处理
如果担心后续HTML结构有变化,可以先获取标签的纯文本,再通过字符串分割提取:
# 获取标签的纯文本,自动忽略注释和多余空格 review_text = res_stats.find("span", attrs={"class": "NoCoR"}).get_text(strip=True) # 按"opiniones"分割,取前面的数字部分 dataframe["number_of_reviews"] = review_text.split('opiniones')[0].strip()
.get_text(strip=True)会合并标签内所有文本并去除首尾空格,得到类似"3 opiniones"的字符串,分割后就能拿到数字。
方法3:正则匹配数字(适配复杂场景)
如果数字前后的文本格式不确定,用正则匹配连续数字会更稳妥:
import re review_tag = res_stats.find("span", attrs={"class": "NoCoR"}) # 匹配一个或多个连续数字 match_result = re.search(r'\d+', review_tag.get_text()) # 存在匹配结果则取数字,否则设为None dataframe["number_of_reviews"] = match_result.group() if match_result else None
这个方法能应对更复杂的文本结构,只要数字是连续的数字字符就能提取到。
把上述方法替换到你的代码中即可,比如用方法1修改后的完整代码:
list_rest =[] for res_name, res_stats in zip(top_rest, top_rest_info): dataframe ={} dataframe["pos"] = res_name.find('a').contents[0] dataframe["name"] = res_name.find('a').contents[-1] # 新增判断避免找不到标签报错 review_tag = res_stats.find("span", attrs={"class": "NoCoR"}) dataframe["number_of_reviews"] = review_tag.contents[0] if review_tag else None list_rest.append(dataframe)
内容的提问来源于stack exchange,提问作者Oswaldo Hernandez
相关产品推荐
相关产品推荐

