如何用BeautifulSoup从多层子链接抓取说唱歌词文本文件?
解决OHHLA说唱歌词抓取的嵌套链接提取问题
核心思路
要实现从嵌套链接中提取所有歌词文本,需要两层嵌套处理:先遍历full_urls中的分类页面,再从每个分类页面抓取指向歌词文本的最终链接,最后提取文本存入数组。用列表推导式结合生成器表达式可实现逻辑扁平化,同时要注意请求合法性与异常规避。
优化后的代码实现
import requests from bs4 import BeautifulSoup from urllib.parse import urljoin base_site = "https://ohhla.com/all.html" # 添加请求头避免被网站拦截 headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"} # 第一步:获取有效分类页面链接 response = requests.get(base_site, headers=headers) soup = BeautifulSoup(response.text, "html.parser") # 直接过滤站内链接并跳过前31个无关项 relative_urls = [a["href"] for a in soup.select("a[href]") if a["href"].startswith("/")][31:] full_category_urls = [urljoin(base_site, url) for url in relative_urls] # 第二步:嵌套提取歌词文本,用双层列表推导式实现 lyrics_array = [ # 提取歌词文本并去除冗余空白 BeautifulSoup(requests.get(urljoin(base_site, lyric_link["href"]), headers=headers).text, "html.parser").get_text(strip=True) # 外层遍历所有分类页面 for category_url in full_category_urls # 内层遍历当前分类下的所有歌词文件链接 for lyric_link in BeautifulSoup(requests.get(category_url, headers=headers).text, "html.parser").select("a[href$='.txt']") ]
关键细节说明
- 双层列表推导式:外层循环处理分类页面,内层循环抓取该分类下的歌词链接并直接提取文本,实现逻辑扁平化
- 链接过滤:用
startswith("/")确保是站内有效链接,href$='.txt'精准定位歌词文件 - 请求合法性:添加
User-Agent模拟浏览器请求,降低被网站拦截的概率 - 健壮性扩展:如果需要避免单个链接请求失败中断整个流程,可以将请求逻辑封装为带
try-except的函数,替换推导式中的请求部分
内容的提问来源于stack exchange,提问作者Bbrown44
相关产品推荐
相关产品推荐

