Python抖音自由互动的脚本--看准绿色部分的txt文件需要自己准备用户连接路径进行测试

这个脚本类似于浏览器点点点,过程不懂的伙伴我们尝试联系。

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os
from selenium.webdriver.common.keys import Keys
# 随机选择一条文本
import random
# 评论区发平台
text_list = [
    "Time doesn't ask about the path you've taken, only if you're still moving forward; may you carry sunshine in your heart and find the world worthwhile after traversing mountains and rivers.",
    "Don't say life is full of storms, turn your smile into a spring breeze; after experiencing the cold and warmth of four seasons, may your heart still hold vibrant colors.",
    "Even if the road ahead is shrouded in fog, believe in the direction of light; as long as hope resides in your heart, there will always be a distant place under your feet.",
    "Every journey through wind and snow is a lesson, every low point is growth; no step in life is wasted, each one brings you closer to your dreams.",
    "Don't envy the fleeting dreams of grandeur, just seek peace in a corner of spring; even in ordinary days, you can live with poetry and deep affection.",
    "Life is like a song and a poem, woven with joys and sorrows; may you live gracefully and brightly in the second half of your life.",
    "Facing storms fearlessly is an attitude, smiling at life's trials is a realm; fifty is not the end, but the best beginning.",
    "Spring has flowers, autumn has the moon, summer has cool breezes, winter has snow; if there's no burden in your heart, every day is a good season.",
    "Living in the present is the most genuine, cherishing the moment is the happiest; even as time passes, keep a youthful heart.",
    "Don't fear going slow, only fear stopping; life has no late starts, only regrets for not setting out.",
    "With light in your heart, you can travel thousands of miles; with a smile on your face, you can enjoy the seasons; may you love passionately and never regret your journey.",
    "Falling down isn't failure, giving up is; as long as you're willing to stand up, fate will open doors for you.",
    "Every day of effort is a prelude to the future; don't fear the lack of applause now, persistence will eventually shine brightly.",
    "Life is a journey of cultivation, growth comes from gains and losses; may you maintain inner peace and kindness amidst chaos.",
    "Life is like rowing against the current, you must keep moving forward; may you not waste your youth and honor your past efforts.",
    "Even without applause, walk gracefully through your stage; your life's script is written by you.",
    "Age is just a number, mindset determines your state; may you shine brighter and become more composed as time goes by.",
    "Instead of envying others' brilliance, light your own beacon; be your own light, illuminating the night and warming others.",
    "Dreams never age, they just hide in your heart; may you wake up one morning and dare to chase them again.",
    "Success isn't the end, growth is the meaning; may every fall bring you closer to a better self.",
    "Time doesn't turn back, but every moment shapes a better you; cherish the present and don't waste the years.",
    "Living itself is a victory, don't give up easily; your existence is a beam of light in this world.",
    "Every morning is a new beginning, don't dwell on yesterday's difficulties; may you start today with hope.",
    "Life has no standard answers, but loving life is always the right choice; may you always hold firm beliefs and move forward bravely.",
    "No matter how many times you fall, keep smiling and moving forward; true strength is choosing to be strong even in tears.",
    "The beauty of life isn't far away, it's in every day you live seriously; may you cherish every moment.",
    "The world is noisy and complex, true happiness comes from inner peace; may you cultivate calmness and self-consistency.",
    "Life is like tea, it has its ups and downs; may you learn to settle in the highs and bloom in the silence.",
    "Every persistence is respect for yourself; may you honor your original intentions, time, and passion.",
    "The future is never far, it's hidden in today's efforts; may you strive with all your might and not disappoint expectations.",
    "Don't fear loneliness or misunderstanding; true winners in life are those who persist in being themselves in solitude.",
    "You don't need to be perfect, just be real; may you remain sincere in a complex world and live your true self.",
    "Life's journey has diverse scenery, may you have the courage to overcome obstacles and the gentleness to savor life.",
    "True maturity is seeing through life yet still loving it; may you shine brighter as you settle in the years.",
    "Dreams have no age limit, passion never expires; may you chase dreams at fifty and keep a youthful heart at eighty.",
    "Life may not be easy, but there's always light waiting for you; may you never give up hope even in the toughest times.",
    "Fate doesn't treat hard-working people unfairly; as long as you're willing to walk, the road will become wider.",
    "Those seemingly ordinary days are quietly paving the way for your dreams; may you not underestimate any day.",
    "Instead of worrying about the future, focus on the present; may you plant seeds of hope in every today.",
    "You may not succeed, but you must grow; may you find your own meaning on the path of continuous progress.",
    "Optimism is a choice and a skill; may you maintain a sunny attitude and smile even in adversity.",
    "May your eyes hold stars and seas, your heart mountains and lakes; wherever you go, never forget love and anticipation.",
    "Don't let yesterday define you, don't let difficulties limit you; may you become a better self in every challenge.",
    "Life has no turning back, but you can change direction; may you always have the courage to change.",
    "Every persistence today is a prelude to tomorrow's surprise; may you not waste time and honor yourself.",
    "As long as there's light in your heart, the night can't stop you from moving forward; may you remain steadfast in confusion.",
    "True happiness is living as you like; may you stay true to yourself on life's journey.",
    "May you smile in good times and stand firm in adversity; this is the most beautiful way to live.",
    "Life's second half isn't slowing down, it's accelerating in a different way; may you replace fatigue with passion and keep moving forward.",
    "Your hard-working self is truly beautiful; may you always shine brightly on the path of struggle.",
    "May you see stars and seas in the mundane, and live a poetic life in the everyday."
]


# 设置 ChromeOptions 以优化性能
chrome_options = Options()
chrome_options.add_argument('--disable-gpu')  # 禁用GPU加速(可选)
chrome_options.add_argument('--no-sandbox')  # 解决DevToolsActivePort文件不存在的报错(Linux环境下)
chrome_options.add_argument('--disable-dev-shm-usage')  # 解决资源限制问题(Linux环境下)

# 初始化 WebDriver
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=chrome_options)

try:
    # 获取当前脚本所在目录
    current_dir = os.path.dirname(os.path.abspath(__file__))
    data_folder = os.path.join(current_dir, "抖音数据")
    links_file_path = os.path.join(data_folder, "用户链接.txt")

    # 检查文件是否存在
    if not os.path.exists(links_file_path):
        print(f"文件 {links_file_path} 不存在,请检查路径和文件名!")
        exit()

    # 读取用户链接并去重
    with open(links_file_path, "r", encoding="utf-8") as file:
        user_links = [line.strip() for line in file.readlines() if line.strip()]

    # 去重处理
    unique_user_links = list(set(user_links))
    print(f"原始链接数:{len(user_links)},初步去重后链接数:{len(unique_user_links)}")

    # 读取“关注链接.txt”文件中的链接
    follow_links_file_path = "关注链接.txt"
    try:
        with open(follow_links_file_path, "r", encoding="utf-8") as follow_file:
            follow_links = set(line.strip() for line in follow_file.readlines() if line.strip())
        print(f"从 '关注链接.txt' 中读取到 {len(follow_links)} 条链接")
    except FileNotFoundError:
        print("未找到 '关注链接.txt' 文件,跳过额外去重步骤")
        follow_links = set()

    # 进一步去重:移除已在“关注链接.txt”中出现的链接
    final_unique_links = [link for link in unique_user_links if link not in follow_links]
    print(f"最终去重后链接数:{len(final_unique_links)}")

    first_run = True
    close_ul_once = True
    comment_count = 0
    # 遍历每个用户链接并执行逻辑
    for index, url in enumerate(final_unique_links, start=1):
        print(f"正在处理第 {index} 条链接:{url}")

        # 在此处添加你的逻辑
        try:
            print(f"\n正在处理第 {index} 个链接:{url}")
            driver.get(url)
            # 只有第一次运行时需要提醒用户进行身份验证
            if first_run:
                input("请完成身份验证后,输入 'm' 继续后续逻辑:")
                first_run = False  # 设置为 False,后续不再提示

            # 等待 class="ty_H89Vr" 的容器出现
            ty_container = WebDriverWait(driver, 60).until(
                EC.presence_of_element_located((By.CLASS_NAME, "LR45FNDp"))
            )
            print("找到 class='LR45FNDp' 的容器")

            # 在该容器中找到所有按钮
            buttons = ty_container.find_elements(By.TAG_NAME, "button")
            if len(buttons) >= 2:  # 确保至少有两个按钮
                second_button = buttons[1]

                # 判断第二个按钮的文本是否已经是 "已关注" 或 "已请求"
                button_text = second_button.text.strip()
                if button_text in ["已关注", "已请求"]:
                    print(f"检测到第二个按钮的文本已是 '{button_text}',跳过此链接的逻辑执行。")
                    continue

                # 移除遮挡元素
                driver.execute_script("""
                    var element = document.querySelector('img.tsASayCJ');
                    if (element) { element.remove(); }
                """)
                print("已移除遮挡的 img 元素")

                # 使用 ActionChains 模拟鼠标停留 0.5 秒后点击第二个按钮
                actions = ActionChains(driver)
                actions.move_to_element(second_button).pause(0.5).click().perform()
                print("已通过模拟鼠标停留 0.5 秒并点击第二个按钮")

                # 等待第二个按钮中的 <span> 文本变为 "已关注" 或 "已请求"
                try:
                    WebDriverWait(driver, 20).until(
                        lambda driver: driver.find_element(By.XPATH, ".//button[2]//span").text.strip() in ["已关注",
                                                                                                            "已请求"]
                    )
                    print("检测到第二个按钮中的文本已变为 '已关注' 或 '已请求'")

                    # 成功关注后,从列表中移除该链接
                    final_unique_links.remove(url)
                    print(f"已从列表中移除链接:{url}")

                except Exception as e:
                    print(f"未检测到文本 '已关注' 或 '已请求',可能操作失败: {e}")

                # =================== 新增逻辑开始 ===================
                # 重新获取按钮列表
                buttons = ty_container.find_elements(By.TAG_NAME, "button")
                if len(buttons) >= 1:  # 确保至少有一个按钮
                    first_button = buttons[0]

                    # 设置最大重试次数和当前重试计数
                    max_retries = 2
                    retry_count = 0

                    while retry_count < max_retries:
                        try:
                            # 使用 ActionChains 模拟鼠标停留 0.5 秒后点击第一个按钮
                            actions = ActionChains(driver)
                            actions.move_to_element(first_button).pause(0.5).click().perform()
                            print(f"已通过模拟鼠标停留 0.5 秒并点击第一个按钮(第 {retry_count + 1} 次尝试)")

                            # 等待 "发送消息" 占位符出现
                            placeholder = WebDriverWait(driver, 5).until(
                                EC.presence_of_element_located(
                                    (By.XPATH,
                                     "//div[@class='public-DraftEditorPlaceholder-inner' and contains(., '发送消息')]"))
                            )
                            print("检测到 '发送消息' 占位符")
                            break  # 如果占位符出现,跳出循环
                        except Exception as e:
                            print(f"未检测到 '发送消息' 占位符,重试中...(错误:{e})")
                            retry_count += 1
                            if retry_count == max_retries:
                                print("已达到最大重试次数,跳过此链接的逻辑执行。")
                                break
                else:
                    print("未找到足够的按钮,请检查页面结构")

                # 找到实际的可编辑输入框(位于 class="DraftEditor-editorContainer" 的容器中)
                try:
                    # 定位 class="DraftEditor-editorContainer" 的容器
                    editor_container = WebDriverWait(driver, 20).until(
                        EC.presence_of_element_located((By.CLASS_NAME, "DraftEditor-editorContainer"))
                    )
                    # 在该容器中找到可编辑的输入框
                    input_box = editor_container.find_element(By.XPATH, ".//div[@contenteditable='true']")
                    if input_box:
                        # 输入指定文本
                        text_to_input = "您好 美好正当下 谢谢你的视频传递 生活可棒,"
                        input_box.send_keys(text_to_input)
                        print(f"已输入文本:{text_to_input}")

                        # 模拟按下 Enter 键发送消息
                        input_box.send_keys(Keys.ENTER)
                        print("已按下 Enter 键发送消息")
                    else:
                        print("未找到可编辑的输入框,请检查页面结构")
                except Exception as e:
                    print(f"查找输入框时出错:{e}")
                time.sleep(0.5)

            # =================== 这部分逻辑与其他逻辑分开 ===================
            # 检查是否需要跳过整个评论逻辑块
            if comment_count >= 150:
                print("已达到最大评论次数(150次),跳过评论逻辑块。")
                break
            else:
                try:
                    # 等待 class="UTSD8keU bGEvyQfj" 的容器出现
                    ut_container = WebDriverWait(driver, 10).until(
                        EC.presence_of_element_located((By.CSS_SELECTOR, "._1PChJilq"))
                    )
                    print("找到 class='._1PChJilq' 的容器")

                    # 查找该容器中的第一个 <li> 元素
                    li_elements = ut_container.find_elements(By.TAG_NAME, "li")
                    if len(li_elements) == 0:
                        print("未找到任何 <li> 元素,跳过此链接的后续逻辑。")
                        continue  # 跳过当前链接,处理下一个链接

                    first_li = li_elements[0]

                    # 模拟鼠标滑动到第一个 <li> 元素位置并停留 0.5 秒后点击
                    actions = ActionChains(driver)
                    actions.move_to_element(first_li).pause(0.5).click().perform()
                    print("已通过模拟鼠标停留 0.5 秒并点击第一个 <li> 元素")
                    time.sleep(1)

                    if close_ul_once:
                        # 查找并移除遮挡的 <ul> 元素
                        ul_element = WebDriverWait(driver, 5).until(
                            EC.presence_of_element_located((By.TAG_NAME, "ul"))
                        )
                        driver.execute_script("arguments[0].remove();", ul_element)
                        print("已移除遮挡的 <ul> 元素")

                        close_ul_once = False  # 确保只执行一次

                    # 等待新页面中的 class="kT7icnwc" 容器出现
                    kT_container = WebDriverWait(driver, 20).until(
                        EC.presence_of_element_located((By.CLASS_NAME, "kT7icnwc"))
                    )
                    print("检测到 class='kT7icnwc' 的容器")

                    # 模拟鼠标滑动到该容器位置并停留 0.5 秒后点击
                    actions = ActionChains(driver)
                    actions.move_to_element(kT_container).pause(0.5).click().perform()
                    print("已通过模拟鼠标停留 0.5 秒并点击 class='kT7icnwc' 的容器")

                    d6_container = WebDriverWait(driver, 20).until(
                        EC.presence_of_element_located((By.CLASS_NAME, "d66pgCnu"))
                    )
                    print("检测到 class='d66pgCnu' 的容器")

                    # 模拟鼠标滑动到该容器位置并停留 0.5 秒后点击
                    actions = ActionChains(driver)
                    actions.move_to_element(d6_container).pause(0.5).click().perform()
                    print("已通过模拟鼠标停留 0.5 秒并点击 class='d66pgCnu' 的容器")
                    time.sleep(0.5)  # 点击后稍作等待

                    # 模拟键盘输入指定文本
                    text_to_input = random.choice(text_list)
                    actions.send_keys(text_to_input).perform()
                    print(f"已输入随机文本:{text_to_input}")
                    time.sleep(1)

                    # 等待 class="Oq4XuF1P" 容器出现
                    try:
                        oq_container = WebDriverWait(driver, 10).until(
                            EC.presence_of_element_located((By.CLASS_NAME, "Oq4XuF1P"))
                        )
                        print("找到 class='Oq4XuF1P' 的容器")

                        # 在该容器中找到所有 <span> 元素
                        spans = oq_container.find_elements(By.TAG_NAME, "span")
                        if len(spans) >= 4:  # 确保至少有四个 <span> 元素
                            fourth_span = spans[3]  # 第四个 <span> 元素(索引从 0 开始)

                            # 查找第四个 <span> 中的 <svg> 元素
                            try:
                                svg_button = fourth_span.find_element(By.TAG_NAME, "svg")
                                print("找到第四个 <span> 中的 <svg> 按钮")

                                # 使用 ActionChains 模拟鼠标点击 <svg> 按钮
                                actions = ActionChains(driver)
                                actions.move_to_element(svg_button).pause(0.5).click().perform()
                                time.sleep(5)
                                print("已通过模拟鼠标停留 0.5 秒并点击第四个 <span> 中的 <svg> 按钮")
                            except Exception as e:
                                print(f"未找到第四个 <span> 中的 <svg> 按钮:{e}")
                        else:
                            print("未找到足够的 <span> 元素,请检查页面结构")
                    except Exception as e:
                        print(f"查找或点击 class='Oq4XuF1P' 容器中的第四个 <span> 时出错:{e}")

                    # 增加计数器
                    comment_count += 1
                    print(f"当前已评论次数:{comment_count}")

                except Exception as e:
                    print(f"评论逻辑块发生错误:{e}")
                    continue  # 如果发生异常,跳过当前链接,继续处理下一个链接

        except Exception as e:
            print(f"处理第 {index} 个链接时出错:{e}")
            continue  # 如果发生异常,跳过当前链接,继续处理下一个链接

finally:
    # 在程序结束时,将更新后的链接列表写回到文件中
    with open(links_file_path, "w", encoding="utf-8") as file:
        for link in final_unique_links:
            file.write(link + "\n")
    print("已更新 '用户链接.txt' 文件")
    # 关闭浏览器前留出时间观察结果
    time.sleep(30)
    driver.quit()
    print("浏览器已关闭,程序结束。")

学会的小伙伴,对于动态网页的操作会有很不错的认识

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值