Files
auto_control/tasks/douyin/actions/like.py
T

106 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""抖音点赞操作。
两种方式:
by_element — 用 xpath 找右侧红心按钮点击(相对定位,不依赖视频卡片序号)
double_click — 双击屏幕中央(兜底,不依赖元素,抖音"双击点赞"手势)
定位器随抖音版本变,by_element 找不到会自动回退双击,不会卡住。
要适配新版本抖音:用 weditor 重新抓当前界面,调整下面定位逻辑。
"""
from core.actions import BaseAction, register_action, should_trigger
from core.logger import get_logger
from . import ACTIONS
_log = get_logger("action.like")
@register_action(ACTIONS)
class LikeAction(BaseAction):
action_type = "like"
name = "点赞"
description = "看完视频后随机点赞(找红心按钮,找不到回退双击)"
default_params = {
"rate": 0.3, # 触发概率 0~1
"method": "by_element", # by_element=找红心 | double_click=双击屏幕
}
def execute(self, d, params, worker):
rate = float(params.get("rate", 0.3))
if not should_trigger(rate):
return False
method = params.get("method", "by_element")
if method == "by_element":
if self._like_by_element(d):
worker.set_action("点赞(红心)")
return True
# 找不到红心,回退双击
ok = self._double_click_center(d)
if ok:
worker.set_action("点赞(双击)")
return ok
@staticmethod
def _like_by_element(d):
"""找右侧操作栏红心按钮点击,成功返回 True。
定位优先级:description 精确 → descriptionContains 模糊 → resourceId → xpath
每种方式找到即点即返回,找不到继续下一种。全程记日志。
"""
# 方式1:description 精确匹配(最稳,不依赖结构)
for desc in ("点赞", "未点赞", "like"):
el = d(description=desc)
if el.exists:
el.click()
_log.info(f"like 命中 description={desc}")
return True
# 方式2:descriptionContains 模糊匹配(适配不同版本文案)
for kw in ("赞", "like"):
el = d(descriptionContains=kw)
if el.exists:
el.click()
_log.info(f"like 命中 descriptionContains={kw}")
return True
# 方式3:resourceId 列表(扩充候选,覆盖更多抖音版本)
for rid in ("com.ss.android.ugc.aweme:id/aky",
"com.ss.android.ugc.aweme:id/d-like-view-icon",
"com.ss.android.ugc.aweme:id/h3r",
"com.ss.android.ugc.aweme:id/dfz",
"com.ss.android.ugc.aweme:id/c5w"):
el = d(resourceId=rid)
if el.exists:
el.click()
_log.info(f"like 命中 resourceId={rid}")
return True
# 方式4:xpath 相对定位——右侧操作栏 LinearLayout 的第一个 ImageView
# 定位思路:ViewPager 下当前 FrameLayout 里的 LinearLayout,
# 取其直接子 FrameLayout 里的第一个 ImageView(点赞在操作栏最上方)
try:
el = d.xpath(
'//androidx.viewpager.widget.ViewPager'
'/android.widget.FrameLayout'
'/com.bytedance.highperformanceview.layout.MeasureOnceRelativeLayout2'
'/com.bytedance.highperformanceview.layout.MeasureOnceRelativeLayout2'
'/android.widget.LinearLayout/android.widget.FrameLayout[2]'
'/android.widget.LinearLayout/android.widget.FrameLayout[1]'
'/android.widget.FrameLayout[1]/android.widget.ImageView'
)
if el.exists:
el.click()
_log.info("like 命中 xpath")
return True
except Exception as e:
_log.warning(f"like xpath 异常: {e}")
_log.info("like_by_element 全部失败,准备回退双击")
return False
@staticmethod
def _double_click_center(d):
"""双击屏幕中央点赞。按屏幕尺寸算坐标,适配不同分辨率。"""
try:
info = d.info
w, h = info["displayWidth"], info["displayHeight"]
d.double_click(int(w * 0.5), int(h * 0.5))
return True
except Exception:
return False