如何使用BeautifulSoup从单个HTML标签中拆分提取独立文本
IMDB Top250爬取数据字段拆分方案
原代码存在的问题
- 循环中引用了未定义的
years变量,运行会直接抛出NameError - 直接提取
titleColumn整段文本做换行替换,会把排名、片名、年份三个独立信息揉成同一字符串,后续拆分容错率低 - 未配置请求头模拟浏览器,大概率会被IMDB反爬拦截,返回错误页面拿不到真实数据
推荐实现方式
不要等拿到合并字符串后再做拆分,直接在解析DOM阶段就定位对应子标签提取独立字段,稳定性更高,不会因为文本格式变化拆分出错。
完整可运行代码如下:
from bs4 import BeautifulSoup import requests import pandas as pd # 配置请求头模拟普通浏览器访问,绕过基础反爬 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" } url = "https://www.imdb.com/chart/top/?ref_=nv_mv_250" resp = requests.get(url, headers=headers) soup = BeautifulSoup(resp.content, "html.parser") data = [] for title_cell in soup.find_all("td", class_="titleColumn"): # 提取排名:取单元格开头的数字,去掉末尾的点号 rank = title_cell.get_text(strip=True).split(".")[0] # 提取电影名:取单元格内a标签的文本 movie_title = title_cell.find("a").get_text(strip=True) # 提取上映年份:取单元格内span标签的文本,去掉两侧括号 release_year = title_cell.find("span", class_="secondaryInfo").get_text(strip=True).strip("()") # 提取对应评分:找相邻的评分单元格内的strong标签文本 score = title_cell.find_next_sibling("td", class_="ratingColumn imdbRating").find("strong").get_text(strip=True) data.append({ "Rank": int(rank), "Title": movie_title, "Year": int(release_year), "Rating": float(score) }) df = pd.DataFrame(data)
运行后得到的DataFrame会自动把排名、片名、年份、评分分成独立列,字段类型也提前做了转换,方便后续分析使用。
备选:已生成合并列的拆分方法
如果你已经跑完原代码拿到了合并后的Title列,也可以用正则直接拆分列,参考代码:
import re # 匹配 排名.片名(年份) 的文本格式 split_pattern = r"(\d+)\.\s*(.+?)\s*\((\d{4})\)" # 从合并的Title列拆分出三个新列 df[["Rank", "Title", "Year"]] = df["Title"].str.extract(split_pattern) # 转换字段类型 df["Rank"] = df["Rank"].astype(int) df["Year"] = df["Year"].astype(int)
内容的提问来源于stack exchange,提问作者beridzeg45
相关产品推荐
相关产品推荐

