使用Beautiful Soup爬取网页失败求助:获取2017年度热门曲目列表
解决BBC节目页面爬取无内容的问题
我帮你排查了这个爬取失败的问题,主要有几个核心原因和对应的解决办法:
1. 静态HTML里没有目标内容(动态加载是关键)
你用urllib.request拿到的是服务器返回的原始静态HTML,但BBC这个节目页面的曲目列表是通过JavaScript动态渲染出来的——你可以自己验证:打开目标页面右键查看“页面源代码”,搜索artist,会发现根本找不到这个类名的元素,它们都是页面加载完成后才生成的。这就是为什么你之前的代码抓不到内容的核心原因。
2. 可能的反爬拦截
urllib的默认请求头太像爬虫了,BBC可能直接返回了不完整的内容或者拦截了请求,这也会导致解析不到目标元素。
解决方案一:用Requests库加自定义请求头尝试静态爬取
先替换urllib为更易用的requests,并设置模拟浏览器的User-Agent,看看能不能获取到内容:
import requests from bs4 import BeautifulSoup my_url = 'http://www.bbc.co.uk/programmes/b09jvtff' # 模拟Chrome浏览器的请求头 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(my_url, headers=headers) page_soup = BeautifulSoup(response.text, "html.parser") # 先检查静态页面里的曲目容器 track_containers = page_soup.find_all('div', class_='tracklist__item') print(track_containers)
如果运行后还是空列表,那基本可以确定是动态加载导致的,需要用无头浏览器来渲染页面。
解决方案二:用Selenium处理动态渲染内容
Selenium可以模拟浏览器完整加载页面,等待JavaScript执行完成后再获取渲染后的HTML,这样就能拿到动态生成的曲目元素了:
from selenium import webdriver from selenium.webdriver.chrome.options import Options from bs4 import BeautifulSoup # 设置无头模式(不弹出浏览器窗口) chrome_options = Options() chrome_options.add_argument("--headless=new") chrome_options.add_argument("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") # 初始化浏览器驱动(需要提前安装对应版本的ChromeDriver) driver = webdriver.Chrome(options=chrome_options) driver.get('http://www.bbc.co.uk/programmes/b09jvtff') # 隐式等待10秒,确保曲目列表加载完成 driver.implicitly_wait(10) # 获取渲染后的页面源码 page_html = driver.page_source page_soup = BeautifulSoup(page_html, "html.parser") # 提取艺术家和曲目名称 tracks = page_soup.find_all('div', class_='tracklist__item') for track in tracks: artist = track.find('span', class_='artist').text.strip() title = track.find('span', class_='title').text.strip() print(f"{artist} - {title}") # 关闭浏览器 driver.quit()
额外小技巧:直接调用API接口
你还可以打开浏览器开发者工具(F12),切换到“网络”标签页,刷新页面后查找XHR请求——BBC大概率有直接返回曲目数据的API接口,直接请求JSON数据会比渲染页面高效得多,也更稳定。比如在这个页面里,你可以找包含tracks或programme关键词的接口,解析返回的JSON就能拿到所有曲目信息。
内容的提问来源于stack exchange,提问作者Chudlee
相关产品推荐
相关产品推荐

