使用BeautifulSoup爬取Shopee页面返回None或空列表的问题求助
问题分析与解决方法
首先得指出你代码里的一个明显小疏漏:你没有正确初始化BeautifulSoup对象!你写的soup = soup(page_html, "html.parser")是错误的,得先导入BeautifulSoup类,再用BeautifulSoup(page_html, "html.parser")来实例化。不过就算修正了这个语法问题,你还是拿不到目标数据——核心原因是Shopee的页面是动态渲染的:你用urllib直接抓取的只是页面的空骨架HTML,实际商品数据是页面加载完成后通过JavaScript动态拉取并渲染出来的,静态HTML里根本不存在_2VIlt8这个类的元素。
具体问题拆解
- 代码语法错误:缺少
BeautifulSoup的导入语句,且实例化对象的写法错误 - 动态内容加载限制:Shopee不会把商品数据直接嵌入初始HTML,而是通过AJAX请求从后端API获取,静态爬虫无法捕获动态生成的内容
解决方法
方法1:用Selenium模拟浏览器加载(新手友好,直观易上手)
Selenium可以模拟真实浏览器打开页面,等待JavaScript加载完成后再获取完整的渲染后HTML,这样就能拿到包含目标元素的页面内容了。
步骤如下:
- 先安装Selenium库,以及对应浏览器的驱动(比如ChromeDriver,要和你本地Chrome版本匹配)
- 修改代码如下:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from bs4 import BeautifulSoup my_url = 'https://shopee.com.my/search?keyword=%E3%80%90local%20ready%20stock%E3%80%91%E3%80%90nero%E3%80%91(00-15)%20anna%20sleepwear%20short%20baju%20tidur%20pyjamas%20pajamas%20sleepwear&page=0&pdpL3Category=100226&shop=426096286&sortBy=sales' # 初始化Chrome浏览器驱动(确保ChromeDriver路径正确,或已配置到环境变量) driver = webdriver.Chrome() driver.get(my_url) # 等待目标元素加载完成,最多等待10秒 try: WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "_2VIlt8")) ) finally: # 获取渲染后的完整页面HTML page_html = driver.page_source driver.quit() # 正确初始化BeautifulSoup并解析 soup = BeautifulSoup(page_html, "html.parser") containers = soup.find("div", attrs={"class":"_2VIlt8"}) print(containers)
方法2:直接调用Shopee的API(高效进阶,速度更快)
Shopee的商品数据是通过公开API接口返回的,你可以直接请求这个接口拿到JSON格式的原始数据,比模拟浏览器加载效率高得多。
你可以通过浏览器开发者工具(F12打开)的Network标签页,过滤XHR请求,找到包含商品数据的API接口(通常是类似https://shopee.com.my/api/v4/search/search_items的地址),然后构造请求参数调用:
import requests # 模拟浏览器请求头,避免被反爬拦截 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Referer': 'https://shopee.com.my/' } api_url = 'https://shopee.com.my/api/v4/search/search_items' # 构造请求参数,对应原URL里的筛选条件 params = { 'keyword': '【local ready stock】【nero】(00-15) anna sleepwear short baju tidur pyjamas pajamas sleepwear', 'page': 0, 'pdp_l3_category': 100226, 'shopid': 426096286, 'sort_by': 'sales' } response = requests.get(api_url, headers=headers, params=params) data = response.json() # 直接打印商品数据,你可以根据需求提取具体字段(比如商品名称、价格等) print(data['items'])
额外注意事项
- Shopee有反爬机制,频繁请求可能会被限制IP,建议添加请求间隔时间,必要时使用代理IP
- 使用Selenium时,务必确保浏览器驱动版本和本地浏览器版本一致,否则会启动失败
内容的提问来源于stack exchange,提问作者Kiki
相关产品推荐
相关产品推荐

