Shopee印尼站爬取:登录元素定位与自动登录问题求助
解决Shopee印尼站自动登录及商品爬取问题
核心问题排查
你的代码无法自动完成登录,根源在于登录弹窗嵌入在iframe中,Selenium默认无法直接定位iframe内部元素;同时商品元素的定位方式也存在错误,导致数据爬取失效。以下是分步修复方案:
登录模块修复
1. 切换到登录iframe上下文
Shopee的登录窗口加载在独立iframe里,必须先切换到该iframe才能操作内部元素:
# 等待登录iframe加载完成并切换 login_iframe = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'iframe[src^="https://accounts.shopee.co.id"]'))) self.driver.switch_to.frame(login_iframe)
2. 修正登录元素定位逻辑
原代码用ID定位稳定性较差,改用属性选择器更可靠,同时补充登录完成后切回主页面的操作:
# 输入账号 wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'input[name="loginKey"]'))).send_keys("你的邮箱/手机号") # 输入密码 wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'input[name="password"]'))).send_keys("你的密码") # 点击登录按钮 wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button.shopee-button-solid.shopee-button-primary'))).click() # 切回主页面上下文 self.driver.switch_to.default_content() # 等待登录完成后商品页面加载 wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.shop-collection-view__item')))
商品爬取模块修复
1. 修正商品列表定位
By.CLASS_NAME不支持传入多个类名,改用CSS选择器定位商品容器:
elements = self.driver.find_elements(By.CSS_SELECTOR, '.col-xs-2.shop-collection-view__item')
2. 商品详情元素定位与异常处理
单个商品的子元素也需要用CSS选择器,同时添加异常处理避免因部分元素缺失导致程序中断:
for element in elements: try: img = element.find_element(By.CSS_SELECTOR, '.wFlKK5').get_attribute('src') # 补充获取图片src属性 name = element.find_element(By.CSS_SELECTOR, '.h0HBrE.ckHqor._5Kkvx1').text price = element.find_element(By.CSS_SELECTOR, '._0ZJOIv').text # 处理可能不存在的评分和销量 rating = element.find_element(By.CSS_SELECTOR, '._01uxti').text if element.find_elements(By.CSS_SELECTOR, '._01uxti') else '0' sale = element.find_element(By.CSS_SELECTOR, '.sPnnFI.AGQcTN').text if element.find_elements(By.CSS_SELECTOR, '.sPnnFI.AGQcTN') else '0' datas.append({ 'img': img, 'name': name, 'price': price, 'sale': sale, 'rating': rating }) except NoSuchElementException: continue # 跳过获取失败的商品
3. 翻页逻辑修复
原XPath定位完全错误,改用Shopee分页按钮的通用选择器:
try: # 定位未禁用的下一页按钮 next_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.shopee-page-controller__next-btn:not([disabled])'))) next_btn.click() # 等待下一页商品元素刷新 wait.until(EC.staleness_of(elements[0])) except NoSuchElementException: print("无更多页面可跳转") break
完整修复代码
from selenium.webdriver.common.by import By from selenium import webdriver from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time class Scraper: def __init__(self): self.driver = webdriver.Firefox() def get_data(self): self.driver.get('https://shopee.co.id/sunxin_store?page=0&sortBy=sales') wait = WebDriverWait(self.driver, 30) # 处理登录流程 try: login_iframe = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'iframe[src^="https://accounts.shopee.co.id"]'))) self.driver.switch_to.frame(login_iframe) wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'input[name="loginKey"]'))).send_keys("你的账号") wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'input[name="password"]'))).send_keys("你的密码") wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button.shopee-button-solid.shopee-button-primary'))).click() self.driver.switch_to.default_content() wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.shop-collection-view__item'))) except Exception as e: print("登录失败或无需登录:", str(e)) counter_page = 0 datas = [] while counter_page < 5: # 滚动加载商品 for _ in range(0, 5000, 500): time.sleep(0.5) self.driver.execute_script("window.scrollBy(0,500)") time.sleep(1) # 预留页面加载时间 # 获取商品列表 elements = self.driver.find_elements(By.CSS_SELECTOR, '.col-xs-2.shop-collection-view__item') for element in elements: try: img = element.find_element(By.CSS_SELECTOR, '.wFlKK5').get_attribute('src') name = element.find_element(By.CSS_SELECTOR, '.h0HBrE.ckHqor._5Kkvx1').text price = element.find_element(By.CSS_SELECTOR, '._0ZJOIv').text rating = element.find_element(By.CSS_SELECTOR, '._01uxti').text if element.find_elements(By.CSS_SELECTOR, '._01uxti') else '0' sale = element.find_element(By.CSS_SELECTOR, '.sPnnFI.AGQcTN').text if element.find_elements(By.CSS_SELECTOR, '.sPnnFI.AGQcTN') else '0' datas.append({ 'img': img, 'name': name, 'price': price, 'sale': sale, 'rating': rating }) except NoSuchElementException: continue print("已爬取 shopee.co.id/sunxin_store 第", counter_page + 1, "页数据") counter_page += 1 # 翻页操作 try: next_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.shopee-page-controller__next-btn:not([disabled])'))) next_btn.click() wait.until(EC.staleness_of(elements[0])) except NoSuchElementException: print("无更多页面可跳转") break return datas # 调用示例 scraper = Scraper() data = scraper.get_data() print(f"共爬取{len(data)}条商品数据") scraper.driver.quit()
额外注意事项
- 反爬规避:Shopee有反爬检测,建议添加随机延迟、更换User-Agent,避免短时间内频繁请求导致账号受限。
- 元素更新:Shopee页面类名可能会不定期更新,若出现定位失败,需用浏览器开发者工具(F12)重新获取最新选择器。
- 验证码处理:若登录时触发验证码,Selenium无法自动处理,需手动验证或使用第三方打码服务。
内容的提问来源于stack exchange,提问作者JeffFederick
相关产品推荐
相关产品推荐

