如何解决Selenium爬取Instagram粉丝的滚动不全与卡顿问题
解决Instagram粉丝爬取的滚动问题:未触底停止与滚动耗时过长
问题1:滚动未触底就停止
你的代码里有几个核心问题导致滚动提前终止:
By.CLASS_NAME不支持传入多个空格分隔的类名,这会直接导致元素定位失败,等待条件提前触发,循环错误终止- 等待条件的逻辑顺序不合理,滚动后应该优先等待新内容加载完成,而不是同时等待多个无关元素
修复方案:
- 把多类名定位换成
CSS_SELECTOR,类名间用.连接(这是CSS选择器处理多类名的标准语法) - 调整等待逻辑:滚动后先等待加载指示器消失,再等待新粉丝项出现,增加超时重试机制,避免单次等待失败就终止循环
- 给滚动操作增加微小延迟,确保页面有足够时间响应滚动事件
问题2:大量粉丝后期滚动耗时过长
当DOM中的粉丝元素积累过多时,每次计算scrollHeight和执行脚本的开销会指数级上升,重复等待多个元素也会浪费大量时间。
优化方案:
- 分批抓取+清理DOM:滚动一段距离后就抓取当前可见的粉丝,然后把已抓取的元素从DOM中移除,减少页面节点数量
- 合并等待条件:避免重复等待相同元素,只保留必要的加载完成判断
- 增量滚动替代全量滚动:不要每次直接滚到底部,可选择每次滚动固定高度(比如1000px),精准控制加载节奏,避免一次性加载过多内容
修改后的完整代码
from selenium.common.exceptions import TimeoutException import time def get_instagram_followers(self): # 优先用相对路径XPATH,避免页面结构变化导致定位失效 followers_panel = self.driver.find_element(By.XPATH, '//div[@class="_aano"]/../../..') last_ht, ht = 0, 1 followers = [] # 加载指示器的CSS选择器(修复多类名定位问题) loading_selector = ".\_ab8w._ab94._ab97._ab9f._ab9m._ab9p._abc0._abcm" # 粉丝项定位选择器 follower_item_selector = '//div[@class="_aano"]//a/span/div' while last_ht != ht: last_ht = ht # 执行滚动操作 ht = self.driver.execute_script(""" arguments[0].scrollTo(0, arguments[0].scrollHeight); return arguments[0].scrollHeight; """, followers_panel) # 加入微小延迟,降低反爬风险同时给页面响应时间 time.sleep(1) try: # 等待加载指示器消失(缩短超时时间,避免无效等待) WebDriverWait(self.driver, 10).until(EC.invisibility_of_element_located((By.CSS_SELECTOR, loading_selector))) # 等待新粉丝项加载完成 WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.XPATH, follower_item_selector))) except TimeoutException: # 超时后重新计算高度,确认是否真的触底 ht = self.driver.execute_script("return arguments[0].scrollHeight", followers_panel) if last_ht == ht: break continue # 增量抓取当前粉丝,过滤已抓取内容 current_items = self.driver.find_elements(By.XPATH, follower_item_selector) new_followers = [item.text for item in current_items if item.text and item.text not in followers] followers.extend(new_followers) # 清理已抓取的DOM元素,减轻页面负担(针对超大量粉丝场景) self.driver.execute_script(""" const items = document.querySelectorAll('div._aano'); items.forEach(item => item.remove()); """) # 重新计算滚动高度,因为DOM已修改 ht = self.driver.execute_script("return arguments[0].scrollHeight", followers_panel) # 最后抓取剩余未处理的粉丝 final_items = self.driver.find_elements(By.XPATH, follower_item_selector) final_followers = [item.text for item in final_items if item.text and item.text not in followers] followers.extend(final_followers) # 去重后返回结果 return list(filter(None, list(set(followers))))
额外注意事项
- Instagram反爬机制严格,滚动间隔不要低于1秒,避免账号被临时限制
- 单次爬取粉丝数量建议控制在5000以内,超量需求分多次执行脚本
- 尽量避免使用绝对路径XPATH,页面结构变更会直接导致定位失败
内容的提问来源于stack exchange,提问作者freeengineer
相关产品推荐
相关产品推荐

