使用BeautifulSoup和Requests进行Python网页爬取时遇到问题
问题:无法用BeautifulSoup提取Metacritic页面的
c-productListings元素 我使用Python的requests库结合BeautifulSoup进行网页爬取,尝试提取目标URL中class为c-productListings的div,但运行后target_div始终返回None。已确认URL可访问、页面HTML结构中存在该元素,更换过BeautifulSoup解析器且请求状态码正常,问题仍未解决。简化代码如下:
from bs4 import BeautifulSoup import requests # 注:原代码遗漏了requests导入 url = "https://www.metacritic.com/browse/movie/all/all/all-time/new/?releaseYearMin=1910&releaseYearMax=2023&page=1" page = requests.get(url) soup = BeautifulSoup(page.content, 'html.parser') target_div = soup.find("div", {"class": "c-productListings"}) print(target_div)
问题原因
- 反爬拦截:Metacritic会检测请求头特征,默认requests的
User-Agent为python-requests/x.x.x,服务器会识别为爬虫,返回的页面不包含目标内容(可能是空白页或验证页面)。 - 动态内容渲染:目标元素可能由JavaScript动态生成,直接用
requests.get只能获取静态HTML源码,无法拿到JS加载后的内容。
解决方法
1. 模拟浏览器请求头
给请求添加符合浏览器特征的User-Agent,绕过基础反爬:
import requests from bs4 import BeautifulSoup url = "https://www.metacritic.com/browse/movie/all/all/all-time/new/?releaseYearMin=1910&releaseYearMax=2023&page=1" # 模拟Chrome浏览器请求头 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Accept-Language": "zh-CN,zh;q=0.9" } page = requests.get(url, headers=headers) # 先验证响应内容是否正常 print(page.status_code) print(len(page.text)) # 若长度过小,说明仍被拦截 soup = BeautifulSoup(page.content, 'html.parser') target_div = soup.find("div", class_="c-productListings") print(target_div)
2. 处理动态渲染内容
如果目标元素是JS动态加载的,使用Selenium模拟浏览器渲染:
from selenium import webdriver from selenium.webdriver.chrome.options import Options from bs4 import BeautifulSoup url = "https://www.metacritic.com/browse/movie/all/all/all-time/new/?releaseYearMin=1910&releaseYearMax=2023&page=1" # 配置无头模式(可选) chrome_options = Options() chrome_options.add_argument("--headless=new") driver = webdriver.Chrome(options=chrome_options) driver.get(url) driver.implicitly_wait(10) # 等待页面加载完成 page_source = driver.page_source soup = BeautifulSoup(page_source, 'html.parser') target_div = soup.find("div", class_="c-productListings") print(target_div) driver.quit()
3. 更稳健的定位方式
- 结合父元素层级缩小查找范围:
main_wrapper = soup.find("div", class_="c-siteWrapper") if main_wrapper: target_div = main_wrapper.find("div", class_="c-productListings") print(target_div)
- 使用CSS选择器(语法更简洁):
target_div = soup.select_one("div.c-productListings") print(target_div)
内容的提问来源于stack exchange,提问作者Masud Al Nahid
相关产品推荐
相关产品推荐

