如何处理Coolmod网站爬虫中的‘Show more’按钮以获取全部产品数据?
解决Coolmod爬虫「Show more」加载更多产品的思路
我看了你的Coolmod爬虫脚本,能正常抓取前20条产品,但碰到了「Show more」加载更多的问题对吧?这类动态加载的内容,一般有两种靠谱的解决方式,我给你拆解下:
方法一:直接抓取分页/加载更多的API接口(推荐)
这种方式比模拟点击高效得多,因为不用加载整个页面的HTML和资源,直接拿数据接口返回的内容。
操作步骤:
- 打开浏览器的开发者工具(按F12),切换到「Network」标签页,过滤「XHR」或「Fetch」请求。
- 点击页面上的「Show more」按钮,观察新出现的请求,找到返回产品数据的那个接口。
- 分析这个接口的参数:通常会带有分页参数,比如
page(页码)、limit(每页条数),或者offset(偏移量)。比如Coolmod的这类接口可能是在原URL后面加&page=2、&page=3这样的参数,或者是一个单独的JSON接口。
代码调整示例:
把你原来的URL循环改成分页请求循环,直到返回的产品为空就停止:
import pandas as pd import requests from bs4 import BeautifulSoup import datetime import time headers = ({ 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36', 'Accept-Language': 'es-ES, es;q=0.5' }) base_url = 'https://www.coolmod.com/componentes-pc-procesadores?f=375::No' df_list = [] page = 1 store = 'Coolmod' extraction_date = datetime.datetime.today().replace(microsecond=0) while True: current_url = f"{base_url}&page={page}" print(f"请求页面:{current_url}") r = requests.get(current_url, headers=headers, timeout=10) print(f"响应状态码:{r.status_code}") soup = BeautifulSoup(r.content,'html.parser') items = soup.find_all('div',class_='col-xs-12 col-sm-6 col-sm-6 col-md-6 col-lg-3 col-product col-custom-width') # 如果没有找到产品,说明已经到最后一页了 if not items: print("没有更多产品,停止请求") break # 处理每个产品的逻辑,和你原来的代码一致 for item in items: product_name = item.find('div',class_ = 'product-name').text.strip().replace('\t','').replace('\n', '').replace('\r', '') try: price = item.find('div', class_ = 'margin-top-20 mod-product-price text-big').text.strip().replace('\t','').replace('\n', '').replace('\r', '') except AttributeError: try: price = item.find('div', class_ = 'mod-product-price text-big').text.strip().replace('\t','').replace('\n', '').replace('\r', '') except AttributeError: price = "No price" try: availability = item.find('div', class_ = 'product-availability cat-product-availability').text.replace('\t','').replace('\n', '').replace('\r', '') except AttributeError: availability = "No info" product_info = { 'product_name' : product_name, 'price' : price, 'availability' : availability, 'store' : store, 'date_extraction' : extraction_date, } df_list.append(product_info) page += 1 time.sleep(3) # 保持请求间隔,避免被封 df = pd.DataFrame(df_list) print(df)
如果发现接口返回的是JSON数据(不是HTML),那你可以直接解析r.json(),不用BeautifulSoup,效率会更高。
方法二:用Selenium模拟点击「Show more」按钮
如果找不到API接口,或者接口有复杂的验证逻辑,就用这个方法模拟真实用户的操作。
准备工作:
- 安装Selenium:
pip install selenium - 下载对应浏览器的驱动(比如ChromeDriver,要和你的Chrome版本匹配),并把驱动放到系统PATH里,或者在代码里指定路径。
代码示例:
import pandas as pd 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 import datetime import time url = 'https://www.coolmod.com/componentes-pc-procesadores?f=375::No' # 初始化浏览器驱动,如果你没把驱动放PATH里,就加 executable_path 参数:executable_path='./chromedriver' driver = webdriver.Chrome() driver.get(url) df_list = [] store = 'Coolmod' extraction_date = datetime.datetime.today().replace(microsecond=0) while True: # 用BeautifulSoup解析当前页面的HTML,复用你原来的解析逻辑 soup = BeautifulSoup(driver.page_source, 'html.parser') items = soup.find_all('div',class_='col-xs-12 col-sm-6 col-sm-6 col-md-6 col-lg-3 col-product col-custom-width') for item in items: product_name = item.find('div',class_ = 'product-name').text.strip().replace('\t','').replace('\n', '').replace('\r', '') try: price = item.find('div', class_ = 'margin-top-20 mod-product-price text-big').text.strip().replace('\t','').replace('\n', '').replace('\r', '') except AttributeError: try: price = item.find('div', class_ = 'mod-product-price text-big').text.strip().replace('\t','').replace('\n', '').replace('\r', '') except AttributeError: price = "No price" try: availability = item.find('div', class_ = 'product-availability cat-product-availability').text.replace('\t','').replace('\n', '').replace('\r', '') except AttributeError: availability = "No info" product_info = { 'product_name' : product_name, 'price' : price, 'availability' : availability, 'store' : store, 'date_extraction' : extraction_date, } df_list.append(product_info) # 尝试点击「Show more」按钮 try: # 等待按钮可点击,超时时间10秒 show_more_btn = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), 'Show more')]")) ) show_more_btn.click() time.sleep(3) # 等待页面加载 except: # 按钮不存在或无法点击,说明没有更多内容了 print("没有更多产品,停止点击") break # 关闭浏览器 driver.quit() df = pd.DataFrame(df_list) print(df)
一些小提示:
- 不管用哪种方法,都要遵守网站的
robots.txt规则,保持合理的请求间隔(你已经加了time.sleep(3),这点做得很好),避免给服务器造成压力,防止被封IP。 - 定期检查网站的HTML结构或API参数,因为网站可能会更新,导致你的解析逻辑失效。
- 可以给
requests.get加个超时时间,比如timeout=10,避免请求卡住。
内容的提问来源于stack exchange,提问作者CMonte2
相关产品推荐
相关产品推荐

