
引言
在上一篇文章《基于Chrome140的FB账号自动化------需求分析&环境搭建(一)》中,我们完成了开发环境的准备工作,包括Python环境配置、uv包管理器安装、Playwright框架部署以及Chrome浏览器的配置。现在,我们将进入核心开发阶段,基于RPA框架构建Facebook自动化浏览系统。
本文将详细介绍如何使用基于动作执行器(action_executor)的RPA框架,实现Facebook的智能浏览、交互和状态管理。通过状态机模式和权重化随机动作系统,我们将构建一个既自然又高效的自动化解决方案。
本教程将展示业务核心内容代码,框架部分将不作为展示。
1. RPA框架架构设计
核心框架结构
基于您提供的代码,我们的Facebook自动化系统采用了成熟的RPA框架设计,具有以下核心特性:
from stubs.rpa import *
from functools import partial
from typing import Tuple
import random
import time
# 核心组件说明
# - CoreBrowsePage: 浏览器页面基类
# - CorePageObject: 页面对象基类
# - action_exector: 动作执行器装饰器
# - start_main_page_process: 主流程启动器
1.1 状态机设计模式
系统采用状态机模式管理不同的页面状态,每个状态对应特定的动作集合:
- home状态:Facebook首页浏览
- detail状态:帖子详情页交互
- unknown状态:异常状态处理
2. 核心动作系统
智能滚动动作
滚动是模拟真实用户浏览行为的基础动作,我们实现了支持随机距离、持续时间和方向的智能滚动系统。
@action_exector
def scroll_action(page: CoreBrowsePage, distance: Tuple[int, int],
duration: Tuple[float, float], scroll_down_probability: int):
"""
智能滚动动作执行器
Args:
page: 浏览器页面对象
distance: 滚动距离范围 (min_distance, max_distance)
duration: 滚动持续时间范围 (min_duration, max_duration)
scroll_down_probability: 向下滚动概率 (0-100)
"""
# 随机生成滚动参数
_distance = random.randint(*distance)
_duration = random.uniform(*duration)
# 获取页面主体元素
_scroll_locator = page.page.locator('body')
# 根据概率决定滚动方向
if random.randint(0, 100) > scroll_down_probability:
# 向上滚动(负值)
_distance = -_distance
page.logger.info(f"执行向上滚动: {abs(_distance)}px, 持续时间: {_duration:.2f}s")
else:
page.logger.info(f"执行向下滚动: {_distance}px, 持续时间: {_duration:.2f}s")
# 执行平滑滚动
smooth_scroll(page.page, _distance, _duration)
2.1 停留动作模拟
停留动作模拟用户阅读和思考的时间,是增强真实性的重要组件:
@action_exector
def stay_action(page: CoreBrowsePage, stay_time: Tuple[int, int]):
"""
用户停留动作模拟器
模拟真实用户在浏览过程中的阅读、思考停顿时间
Args:
page: 浏览器页面对象
stay_time: 停留时间范围 (min_seconds, max_seconds)
"""
# 随机生成停留时间
_stay_duration = random.uniform(*stay_time)
page.logger.info(f"用户停留思考: {_stay_duration:.2f}秒")
# 执行等待
time.sleep(_stay_duration)
# 如果需要截图可以添加截图记录执行
page.save_html_and_screenshot() # 保存html内容和截图
page.logger.info("停留结束,继续浏览")
3. 内容交互系统
智能帖子选择与点击
内容交互是Facebook自动化的核心功能,我们实现了智能的帖子识别和点击系统:
@action_exector
def detail_action(page: CorePageObject):
"""
智能帖子详情页进入动作
自动识别当前视口内的可点击内容,优先选择图片和视频帖子
"""
page.logger.info("开始搜索可点击的帖子内容")
_selected_post = None
# 第一优先级:搜索图片帖子
_photo_post_locators = page.page.locator('[data-virtualized="false"] .html-div > a')
for _article_locator in _photo_post_locators.all():
# 检查链接是否包含photo关键词
href_attr = _article_locator.get_attribute('href')
if not href_attr or "photo" not in href_attr:
continue
# 检查元素是否在视口内且可点击
if element_in_viewport(page.page, _article_locator) and _article_locator.is_enabled():
_selected_post = _article_locator
page.logger.info(f"找到可点击的图片帖子: {href_attr}")
break
# 第二优先级:搜索视频帖子
if not _selected_post:
page.logger.info("未找到图片帖子,搜索视频内容")
_video_post_locators = page.page.locator('[data-virtualized="false"] .html-div video')
for _video_post_locator in _video_post_locators.all():
if element_in_viewport(page.page, _video_post_locator) and _video_post_locator.is_enabled():
_selected_post = _video_post_locator
page.logger.info("找到可点击的视频帖子")
break
# 执行点击操作
if not _selected_post:
page.logger.info("当前视口内未找到可点击的帖子内容")
return
# 记录点击信息
page.logger.info(f"准备点击帖子元素: {_selected_post}")
try:
bounding_box = _selected_post.bounding_box()
if bounding_box:
page.logger.info(f"帖子位置信息: x={bounding_box['x']}, y={bounding_box['y']}, "
f"width={bounding_box['width']}, height={bounding_box['height']}")
except Exception as e:
page.logger.warning(f"获取元素位置信息失败: {e}")
# 执行模拟鼠标点击
page.logger.info("执行帖子点击操作")
simulate_mouse_click(page.page, _selected_post.first)
3.1 返回导航动作
返回动作确保用户能够从详情页回到主页面继续浏览:
@action_exector
def back_action(page: CorePageObject):
"""
页面返回导航动作
从帖子详情页返回到主页面,并等待页面加载完成
"""
page.logger.info("执行页面返回操作")
# 执行浏览器返回
page.page.go_back()
# 等待页面稳定
page.logger.info("等待页面加载完成...")
page.page.wait_for_timeout(5000) # 固定等待5秒
page.page.wait_for_load_state() # 等待页面加载状态
page.logger.info("页面返回完成")
4. Facebook页面控制器
FBBrowsePage核心类
Facebook浏览页面类是整个系统的核心控制器,管理页面状态、动作权重和异常处理:
# 详情页URL关键词定义
_DETAIL_URL_KEYWORDS = [
"photo", # 图片帖子
"watch", # Watch视频
"video", # 普通视频
"reel", # Reels短视频
"live", # 直播内容
]
class FBBrowsePage(CoreBrowsePage):
"""Facebook自动化浏览页面控制器"""
@property
def url(self):
"""Facebook主页URL"""
return "https://facebook.com"
@property
def random_actions(self):
"""
状态化随机动作配置系统
根据当前页面状态返回对应的动作权重配置
每个动作都有对应的权重值,系统会根据权重随机选择执行
"""
return {
# 主页状态动作配置
"home": [
# (权重, 动作函数)
(self.scroll_weight, partial(
scroll_action,
distance=self.scroll_distance,
duration=self.scroll_time,
scroll_down_probability=self.scroll_down_probability
)),
(self.stay_weight, partial(
stay_action,
stay_time=self.home_stay_time
)),
(self.view_detail_weight, partial(detail_action)),
],
# 详情页状态动作配置
"detail": [
# 详情页不执行滚动,主要是停留和返回
(self.stay_weight, partial(
stay_action,
stay_time=self.home_stay_time
)),
(self.go_back_weight, partial(back_action)),
],
}
4.1 登录状态检测
def is_login(self):
"""
Facebook登录状态检测
通过检查当前页面URL来判断是否成功登录
登录成功后应该停留在Facebook主页
Returns:
bool: True表示已登录,False表示未登录或登录失败
"""
try:
# 等待页面加载完成
self.page.wait_for_load_state()
# 检查URL是否为Facebook主页
current_url = self.page.url.strip('/')
expected_url = "https://www.facebook.com"
if current_url != expected_url:
self.logger.warning(f"当前页面URL不匹配: {current_url} != {expected_url}")
return False
self.logger.info("Facebook登录状态检测通过")
return True
except Exception as e:
self.logger.error(f"登录状态检测失败: {e}")
return False
4.2 页面状态识别
def get_current_state(self):
"""
智能页面状态识别系统
根据当前页面URL自动识别页面状态,用于动作选择
Returns:
str: 页面状态 ("home", "detail", "unknown")
"""
_current_page_url = self.page.url
self.logger.info(f"当前页面URL分析: {_current_page_url}")
# Facebook主页状态
if _current_page_url.strip('/') == "https://www.facebook.com":
self.logger.info("识别为主页状态 (home)")
return "home"
# 详情页状态检测
if any(keyword in _current_page_url for keyword in _DETAIL_URL_KEYWORDS):
self.logger.info(f"识别为详情页状态 (detail)")
return "detail"
# 未知状态
self.logger.warning(f"未知页面状态: {_current_page_url}")
return "unknown"
def check_exception_handler(self):
"""
异常状态处理器
在每个随机动作执行前检查页面是否出现异常情况
例如:弹出对话框、验证码、错误页面等
可以在这里添加各种异常情况的处理逻辑
"""
try:
# 检查是否有阻塞性弹窗
modal_selectors = [
'[role="dialog"]',
'.modal',
'[data-testid="cookie-policy-manage-dialog"]',
'[aria-label*="关闭"]'
]
for selector in modal_selectors:
elements = self.page.locator(selector)
if elements.count() > 0:
self.logger.warning(f"检测到弹窗元素: {selector}")
# 这里可以添加关闭弹窗的逻辑
break
except Exception as e:
self.logger.error(f"异常检查处理失败: {e}")
5. 系统启动与配置
主流程启动配置
系统启动使用框架提供的start_main_page_process
函数,支持重试机制和超时控制:
# 系统主流程启动
start_main_page_process(
self, # 页面实例
FBBrowsePage, # Facebook页面控制器类
retry=1, # 失败重试次数
timeout=60000 # 超时时间(毫秒)
)
5.1 配置参数说明
Facebook自动化系统的行为通过以下权重参数进行调控:
# 动作权重配置示例
class FBBrowsePage(CoreBrowsePage):
def __init__(self):
super().__init__()
# 滚动相关配置
self.scroll_weight = 40 # 滚动动作权重
self.scroll_distance = (200, 600) # 滚动距离范围(像素)
self.scroll_time = (0.5, 2.0) # 滚动持续时间(秒)
self.scroll_down_probability = 80 # 向下滚动概率(%)
# 停留相关配置
self.stay_weight = 30 # 停留动作权重
self.home_stay_time = (3, 8) # 主页停留时间范围(秒)
# 交互相关配置
self.view_detail_weight = 20 # 查看详情权重
self.go_back_weight = 80 # 返回操作权重
额外说明
框架依赖说明
本系统基于成熟的RPA框架构建,主要依赖组件包括:
# 核心依赖模块
from stubs.rpa import (
CoreBrowsePage, # 浏览器页面基类
CorePageObject, # 页面对象基类
action_exector, # 动作执行器装饰器
smooth_scroll, # 平滑滚动函数
element_in_viewport, # 视口检测函数
simulate_mouse_click, # 鼠标点击模拟
start_main_page_process # 主流程启动器
)
最佳实践建议
- 权重调优:根据实际需求调整各动作的权重比例
- 时间控制:合理设置停留时间和滚动持续时间
- 异常处理 :完善
check_exception_handler
方法的异常检测逻辑 - 日志记录:充分利用页面对象的logger进行调试和监控
- 状态管理:根据业务需求扩展更多的页面状态
结语
本文详细介绍了基于RPA框架的Facebook自动化浏览系统实现方案。通过动作执行器模式、状态机管理和权重化随机动作系统,我们构建了一个功能完整、行为自然的自动化解决方案。
核心技术特点:
- 基于装饰器的动作执行器模式,代码结构清晰
- 状态机管理不同页面的行为策略
- 权重化随机动作系统,模拟真实用户行为
- 智能内容识别和交互机制
- 完善的异常检测和处理框架
系统优势:
- 高度模块化的设计,易于扩展和维护
- 基于成熟RPA框架,稳定性有保障
- 智能的页面状态识别和动作选择
- 丰富的配置参数,适应不同使用场景
通过本文的学习,您已经掌握了Facebook自动化系统的核心开发技术。在下一篇文章《基于Chrome140的FB账号自动化------运行脚本(三)》中,我们将重点介绍系统的部署运行、监控管理和性能优化,帮助您将开发完成的自动化脚本投入实际应用。