PulsarRPA - 适用于网络爬虫和 AI agents 的高性能分布式 RPA

视频介绍了如何使用 PulsarRPA,来完整精确地采集和管理最复杂的电商数据。

我们以 Amazon 为例,为了展示我们解决的是 Amazon 全球站点的问题,而不单单是个别网站的问题,我们就以 Amazon 英国站为例。

PulsarRPA - 适用于网络爬虫和 AI agents 的高性能分布式 RPA

PulsarRPA 同时打开很多个商品页面,滚动到页面底部,确保所有信息均完整呈现。

尤其值得注意的是,PulsarRPA 执行了一个高难度动作:点击打开 seller 信息面板,同 seller 信息面板交互,等待 seller 信息完整加载。

和其他 RPA 不同的是,PulsarRPA 的性能非常高,这就意味着成本非常低,一台普通机器,每天访问十万、几十万网页,采集数千万、上亿数据点,毫无压力。

PulsarRPA 也包含了一系列其他黑科技,包括使用监督学习、无监督学习技术自动提取大批量网站,我们将在其他视频中介绍。

这里 PulsarRPA 是打开了4套浏览器,每一套浏览器都代表了一个独立的用户去访问网站,每个用户又同时打开了很多个页面。

如果我们有大量的网页需要采集或者监控,那么同时打开成千上万个网页,也是很正常的事情。

为了演示效果,让大家看到PulsarRPA访问每一个网页的具体过程,我们让chrome浏览器显示了图像化界面。

在生产环境中,我们也可以不显示浏览器的图像化界面,从而节约系统资源,提高系统性能,降低总体成本。

从日志中可以看到,在这台机器上,系统性能大致是每秒钟两个网页。

由于每天有86,400秒,按照这个速度,一台机器每天大约可以采集17万个网页。

咱们的高性能分布式RPA在网页上执行了交互动作,保证了所有字段均完整呈现在页面上,每个页面会有100~200个高价值字段被提取出来。因此一台机器一天就可以采集1700万到3400万个字段,并且存入数据库。

如果考虑到详情页上的评论信息,这个数据将会更加庞大。

现在我们看一下数据提取结果。默认情况下,所有数据均保存到了数据库。同时,为了我们方便查看,也保存了一小部分到文件系统中,可以直接打开。

除了高性能分布式网上冲浪外,PulsarRPA也提供了一系列其他黑科技。

基于无监督学习的自动网页提取,和网页理解技术,来提取超大规模网页数据,或者支持 AI agents准确识别网页元素。

基于监督学习的网页提取技术,适用于大批量不同的网站进行数据提取,一次训练,永久有效。

欢迎关注 platon.ai 的其他视频和资料。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是适用于混合环境和离散动作空间的MADDPG代码示例: ```python import numpy as np import torch import torch.nn as nn import torch.optim as optim # 定义 Actor 和 Critic 网络 class Actor(nn.Module): def __init__(self, state_dim, action_dim, hidden_size): super(Actor, self).__init__() self.fc1 = nn.Linear(state_dim, hidden_size) self.fc2 = nn.Linear(hidden_size, hidden_size) self.fc3 = nn.Linear(hidden_size, action_dim) def forward(self, state): x = torch.relu(self.fc1(state)) x = torch.relu(self.fc2(x)) x = torch.tanh(self.fc3(x)) return x class Critic(nn.Module): def __init__(self, state_dim, action_dim, hidden_size): super(Critic, self).__init__() self.fc1 = nn.Linear(state_dim + action_dim, hidden_size) self.fc2 = nn.Linear(hidden_size, hidden_size) self.fc3 = nn.Linear(hidden_size, 1) def forward(self, state, action): x = torch.cat([state, action], dim=1) x = torch.relu(self.fc1(x)) x = torch.relu(self.fc2(x)) x = self.fc3(x) return x # 定义 MADDPG 类 class MADDPG: def __init__(self, state_dim, action_dim, hidden_size, discount_factor=0.99, tau=0.01, learning_rate=0.001): self.num_agents = len(state_dim) self.discount_factor = discount_factor self.tau = tau # 初始化 Actor 和 Critic 网络 self.actors = [Actor(state_dim[i], action_dim[i], hidden_size) for i in range(self.num_agents)] self.target_actors = [Actor(state_dim[i], action_dim[i], hidden_size) for i in range(self.num_agents)] self.critics = [Critic(sum(state_dim), sum(action_dim), hidden_size) for i in range(self.num_agents)] self.target_critics = [Critic(sum(state_dim), sum(action_dim), hidden_size) for i in range(self.num_agents)] # 初始化 Actor 和 Critic 优化器 self.actor_optimizers = [optim.Adam(actor.parameters(), lr=learning_rate) for actor in self.actors] self.critic_optimizers = [optim.Adam(critic.parameters(), lr=learning_rate) for critic in self.critics] # 将 target 网络参数设置为与本地网络相同 for i in range(self.num_agents): self.target_actors[i].load_state_dict(self.actors[i].state_dict()) self.target_critics[i].load_state_dict(self.critics[i].state_dict()) def get_actions(self, states, noise_scale=0.1): actions = [] for i in range(self.num_agents): state = torch.FloatTensor(states[i]).unsqueeze(0) action = self.actors[i](state).squeeze(0).detach().numpy() noise = noise_scale * np.random.randn(*action.shape) action = np.clip(action + noise, -1, 1) actions.append(action) return actions def update(self, states, actions, rewards, next_states, dones): states = [torch.FloatTensor(np.concatenate(states, axis=1))] actions = [torch.FloatTensor(np.concatenate(actions, axis=1))] rewards = [torch.FloatTensor(rewards)] next_states = [torch.FloatTensor(np.concatenate(next_states, axis=1))] dones = [torch.FloatTensor(dones)] # 更新 Critic 网络 target_actions = [] for i in range(self.num_agents): target_actions.append(self.target_actors[i](next_states[i]).detach()) target_actions = torch.cat(target_actions, dim=1) target_q_values = [] for i in range(self.num_agents): target_q_values.append(self.target_critics[i](next_states[0], target_actions).detach()) target_q_values = torch.cat(target_q_values, dim=1) target_q_values = rewards[0] + (self.discount_factor * target_q_values * (1 - dones[0])) q_values = [] for i in range(self.num_agents): q_values.append(self.critics[i](states[0], actions[0][:, sum(self.num_agents[:i]):sum(self.num_agents[:i+1])])) critic_losses = [] for i in range(self.num_agents): critic_losses.append(nn.functional.mse_loss(q_values[i], target_q_values[:, i:i+1])) for i in range(self.num_agents): self.critic_optimizers[i].zero_grad() critic_losses[i].backward() self.critic_optimizers[i].step() # 更新 Actor 网络 updated_actions = [] for i in range(self.num_agents): updated_actions.append(self.actors[i](states[0][:, sum(self.num_agents[:i]):sum(self.num_agents[:i+1])])) updated_actions = torch.cat(updated_actions, dim=1) actor_losses = [] for i in range(self.num_agents): actor_losses.append(-self.critics[i](states[0], updated_actions[:, sum(self.num_agents[:i]):sum(self.num_agents[:i+1])]).mean()) for i in range(self.num_agents): self.actor_optimizers[i].zero_grad() actor_losses[i].backward() self.actor_optimizers[i].step() # 更新 target 网络参数 for i in range(self.num_agents): for local_params, target_params in zip(self.actors[i].parameters(), self.target_actors[i].parameters()): target_params.data.copy_(self.tau * local_params.data + (1 - self.tau) * target_params.data) for local_params, target_params in zip(self.critics[i].parameters(), self.target_critics[i].parameters()): target_params.data.copy_(self.tau * local_params.data + (1 - self.tau) * target_params.data) ``` 其中,`state_dim` 是代理的状态空间维度的列表,`action_dim` 是代理的动作空间维度的列表,`hidden_size` 是 Actor 和 Critic 网络的隐藏层大小,`discount_factor` 是折扣因子,`tau` 是软更新参数,`learning_rate` 是 Actor 和 Critic 网络的学习率。`get_actions` 方法返回代理的动作,`update` 方法更新 Actor 和 Critic 网络参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值