使用Selenium抓取JS驱动的Zalora网站:两页面脚本内容重复问题
问题分析与解决方案
首先先提个代码里的小笔误:在获取第二页脚本时,你一开始写了page_script_2 = soup.findAll('script')[40].text,这里的soup其实是第一页的soup_1——不过后面你又用soup_2重新获取了,所以这个错误不是导致两个脚本内容一致的核心原因,但还是得修正避免后续出问题。
核心问题出在Zalora印尼站是重度依赖JavaScript的单页应用(SPA):这类网站切换页面时不会完全刷新整个浏览器窗口,而是通过前端路由动态加载内容。当你调用browser.get(url2)后立刻抓取page_source,浏览器很可能还没完成新页面的渲染,导致拿到的还是第一页的缓存内容。另外,通过固定索引script[40]获取脚本的方式非常不可靠——不同页面的脚本标签数量、位置可能动态变化,你取到的可能始终是同一个全局缓存的脚本。
针对你抓取全页产品信息的需求,我整理了修正方向和优化后的代码:
1. 关键优化点
- 等待页面完全加载:用Selenium的
WebDriverWait等待特定元素出现,确保新页面内容渲染完毕 - 精准定位数据脚本:不再依赖固定索引,而是通过匹配脚本里的全局变量关键词(电商网站通常会把产品数据存在全局变量里)来定位目标脚本
优化后的代码示例
from pyvirtualdisplay import Display 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 import json import time import random display = Display(visible=0, size=(800, 600)) display.start() browser = webdriver.Chrome() wait = WebDriverWait(browser, 10) # 设置10秒超时,可根据网络情况调整 def get_page_product_data(page_url): browser.get(page_url) # 等待产品卡片加载完成(选择器可根据页面实际结构调整) wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "div[class*='product-card']"))) # 等待URL完全更新,确保页面跳转完成 wait.until(EC.url_to_be(page_url)) # 随机延迟,避免触发反爬 time.sleep(random.uniform(2, 4)) soup = BeautifulSoup(browser.page_source, 'html5lib') # 遍历脚本,找到存储产品数据的全局变量 for script in soup.find_all('script'): script_text = script.text.strip() # 电商站通常会用类似__INITIAL_STATE__的变量存初始数据 if '__INITIAL_STATE__' in script_text: # 提取JSON格式的产品数据 start_mark = 'window.__INITIAL_STATE__ = ' start_idx = script_text.find(start_mark) + len(start_mark) end_idx = script_text.find(';', start_idx) product_data = json.loads(script_text[start_idx:end_idx]) return product_data # 获取第1页产品数据 page1_data = get_page_product_data('https://www.zalora.co.id/women/pakaian/atasan/?gender=women&dir=desc&sort=popularity&category_id=704&page=1') # 获取第2页产品数据 page2_data = get_page_product_data('https://www.zalora.co.id/women/pakaian/atasan/?gender=women&dir=desc&sort=popularity&category_id=704&page=2') # 验证数据是否不同(打印产品数量) print(f"第1页产品数量:{len(page1_data['products']['list'])}") print(f"第2页产品数量:{len(page2_data['products']['list'])}") browser.quit() display.stop()
额外注意事项
- 反爬应对:Zalora有反爬机制,频繁抓取可能被封IP,建议添加随机延迟、使用代理IP,或者模拟真人操作(比如偶尔滚动页面)
- 动态加载处理:如果部分页面需要滚动到底部加载更多产品,可以添加滚动逻辑:
browser.execute_script("window.scrollTo(0, document.body.scrollHeight);"),然后等待新内容加载 - 全局变量调整:如果
__INITIAL_STATE__不对,你可以打开浏览器开发者工具,在Console里输入window查看全局变量,找到存储产品数据的具体变量名
内容的提问来源于stack exchange,提问作者nsinthunont
相关产品推荐
相关产品推荐

