python利用ai生成微头条及相关自动操作功能。

今天要完成的是自动生成微头条,并添加商品卡。做的是图书推荐,图书目录取自douban,然后利用ai生成荐书稿,然后发布到微头条,并添加商品卡。需要注意的是商品卡功能需要头条粉丝达到一定的数量。如果不到的话,可以每日发布,拉粉。做垂直。

0.基础准备

请参考文章:python自动操作浏览器的完善-CSDN博客

1.打开微头条等。

分析:在Selenium中,当你通过driver.window_handles获取所有窗口句柄时,它会返回一个列表,其中包含了当前打开的所有窗口的句柄。这个列表的索引是从0开始的。
如果您手动关闭了一个新打开的窗口,然后再次执行打开新窗口的操作,之前被关闭的窗口句柄将不再有效。此时,如果直接使用之前的索引(如您的例子中的i=1),可能会因为索引错误而导致无法正确切换到新打开的窗口。
因此,确实需要对i进行调整以指向最新打开的窗口。一种更稳健的做法是直接定位到最新的窗口,而不是固定使用索引。可以稍微修改您的代码如下:

# 打开新窗口
driver.execute_script("window.open('');")

# 切换到最新打开的窗口,即最后一个窗口句柄
driver.switch_to.window(driver.window_handles[-1])

# 导航到目标网址
driver.get("https://mp.toutiao.com/profile_v4/weitoutiao/publish")

 

2.douban,获取图书资源,并提取出图书名称。

代码只参考,请处理修改。

import requests
from bs4 import BeautifulSoup

def fetch_book_titles(url):
    # 发送HTTP GET请求
    response = requests.get(url)
    
    # 检查请求是否成功
    if response.status_code == 200:
        # 使用BeautifulSoup解析网页内容
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # 找到包含书籍名称的元素,这里假设书籍名称在特定的HTML标签中,例如<li class="title">
        # 注意:实际的标签和类名可能与示例不同,需要根据实际网页结构调整
        book_list = soup.find_all('li', class_='title')
        
        # 提取书籍名称并存储到数组中
        book_titles = [book.text.strip() for book in book_list]
        
        return book_titles
    else:
        print(f"请求失败,状态码:{response.status_code}")
        return []

# 目标网页URL
url = "https://book.douban.com/chart?subcat=literary"

# 调用函数并打印结果
book_titles = fetch_book_titles(url)
print(book_titles)

 修正部分。

首先寻找所有具有class="clearfix"的<h2>标签,然后从中提取每个<h2>内的<a>标签的文本内容,即书名,并存储到book_titles列表中。注意,这里使用了列表推导式,并且通过条件if a.a来确保只有包含<a>标签的<h2>元素被考虑,尽管在这个特定上下文中可能不是必要的,因为<h2>下通常直接包含<a>。

soup = BeautifulSoup(response.text, 'html.parser')

# 直接定位到包含书名的<a>标签,这些<a>标签位于具有'class="clearfix"'的<h2>标签内
book_titles = [a.text.strip() for a in soup.find_all('h2', class_='clearfix') if a.a]
# 或者更精确地定位到<h2>内的<a>
# book_titles = [a.text.strip() for h2 in soup.find_all('h2', class_='clearfix') for a in h2.find_all('a')]

return book_titles

 为了防止有同名的书,所以把作者也提取出来。

soup = BeautifulSoup(response.text, 'html.parser')

# 定位到每个书籍条目
book_items = soup.find_all('li', class_='media clearfix')

book_info_list = []
for item in book_items:
    # 提取书名
    title_tag = item.find('a', class_='fleft')
    title = title_tag.text.strip() if title_tag else ''
    
    # 在同一个<li>下寻找包含作者信息的<p>标签
    abstract_tag = item.find('p', class_='subject-abstract')
    if abstract_tag:
        # 假设作者名在文本中以"/"分隔的第一部分,这需要根据实际情况调整
        author_info = abstract_tag.text.split('/')[0].strip()
        # 构建带有作者信息的书名
        full_title = f"{title}(作者:{author_info})"
    else:
        # 如果找不到作者信息,仅使用书名
        full_title = title
    
    book_info_list.append(full_title)

return book_info_list

这个有意思,每页的最后一个用的class不一样。所以再修改

book_items = soup.select('li.media.clearfix, li.media.clearfix.last')

测试通过。

3.把信息写入ini。参考代码:可以计算成功多少条,失败多少条。

import configparser

# 假设这是你从网页抓取到的书籍信息列表
book_info_list = [
    {"title": "阿勒泰的角落", "author": "李娟"},
    # ... 其他书籍信息
]

# ini文件路径
ini_file_path = "books.ini"

# 初始化计数器
success_count = 0
fail_count = 0

# 初始化ConfigParser对象
config = configparser.ConfigParser()
config.read(ini_file_path)  # 读取现有ini文件内容

# 遍历书籍信息,检查并写入
for book in book_info_list:
    # 创建书籍条目作为section的名称,格式为"书名(作者)"
    section_name = f"{book['title']}(作者:{book['author']})"
    
    # 检查该section是否已存在
    if section_name not in config.sections():
        # 如果不存在,则添加section,并设置键值
        config.add_section(section_name)
        config.set(section_name, "toutiao", "")
        success_count += 1  # 成功更新计数+1
    else:
        fail_count += 1  # 如果section已存在,视为失败,计数+1

# 写入或更新ini文件
with open(ini_file_path, "w") as configfile:
    config.write(configfile)

# 输出结果
print(f"书籍信息处理完成。成功更新:{success_count}条,失败:{fail_count}条.")

4.再完善一下,把周榜全部读下来,此方案可以把所有的打算介绍的书籍读下来。

categories = [
    "literary",
    "novel",
    "history",
    "social",
    "tech",
    "art",
    "drama",
    "business",
    "comics",
    "suspense_novel",
    "science_fiction"
]

base_url = "https://book.douban.com/chart?subcat="

# 生成完整网址列表
full_urls = [base_url + category for category in categories]

# 打印每个网址
for url in full_urls:
    print(url)

5.由于每周数据有重合,所以要读取出来,另外每次只发5个书籍。不可能一次性完成,所以要读取该toutiao的书是否已经推荐。把没有推荐的提取成数组,并且只返加前五个。不必要全部返回。

def read_key_values_from_ini(file_path, key, limit=5):
    """
    读取.ini文件中所有section的指定key值,返回一个最多包含limit个元素的列表。

    :param file_path: .ini文件的路径
    :param key: 要读取的键名
    :param limit: 返回结果的最大数量,默认为5
    :return: 包含指定key值的列表,如果不足limit个,则返回实际数量并附带提示信息
    """
    config = configparser.ConfigParser()
    config.read(file_path)
    # 打印所有的sections,确认section是否正确读取
    print("Sections:", config.sections())

    sections_with_empty_toutiao = [
        section for section in config.sections()
        if not config.has_option(section, key) or config.get(section, key).strip() == ''#两个条件,前者没有这个key的,后者这个key的值为空的
    ]

    print("Sections with empty 'toutiao':")
    # for section in sections_with_empty_toutiao:
    #     pass
        # print(section)
    result = sections_with_empty_toutiao[:limit]

    if len(result) < limit:
        print(f"本次符合条件的只有{len(result)}个")

    return result

 6.将取出的书名当成变量,在Ai对话中使用,在商品卡中使用。将从kimi取得的答案置入编辑框。

7.可能遇到的问题:

模拟操作时,如何定位链接,并点击

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

# 设置ChromeDriver服务
service = Service(ChromeDriverManager().install())

# 启动Chrome浏览器
driver = webdriver.Chrome(service=service)

# 打开网页
driver.get("http://example.com")  # 将这里的URL替换为你想要打开的网页地址

# 定位链接
# 这里假设链接的文本是"点击这里"
link_to_click = driver.find_element(By.LINK_TEXT, "点击这里")

# 或者,如果想通过href属性定位(例如href="https://www.example.com/somepage")
# link_to_click = driver.find_element(By.XPATH, "//a[@href='https://www.example.com/somepage']")

# 点击链接
link_to_click.click()

# 等待一段时间,以便观察页面变化,或者直接进行后续操作
# driver.implicitly_wait(10)  # 隐式等待,单位秒

# 关闭浏览器
# driver.quit()

 

<div class="byte-tabs-header-title active">精选联盟</div> 这个一个按钮,如何在模拟操作中让其active 状态。点击无用。

from selenium import webdriver
from selenium.webdriver.common.by import By

# 启动浏览器和打开网页的代码同上...

# 定位到目标元素
element = driver.find_element(By.CSS_SELECTOR, "div.byte-tabs-header-title")

# 使用JavaScript改变元素的类名,使其变为active
driver.execute_script("arguments[0].classList.add('active');", element)

# 确认操作是否生效,这一步根据实际情况可能不需要
if "active" in element.get_attribute("class"):
    print("元素状态已变为active")
else:
    print("未能成功改变元素状态")

# 记得在操作完成后关闭浏览器
# driver.quit()

即定位并操作“精选联盟”的“添加更多”按钮。然而,你提到的代码片段中并没有直接展示wait_for_element_located函数的定义,这个函数应该是自定义的用于等待元素出现的函数。基于你的描述,我将提供一个包含等待逻辑的修改版代码,假设wait_for_element_located是一个模拟的显式等待函数。此外,由于你要求的是针对“精选联盟”标题变为active状态,我将结合之前讨论的直接操作DOM的方法来尝试实现这一需求。但请注意,直接改变DOM状态可能不符合页面原本的设计逻辑,仅作示例之用。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

# 假设的wait_for_element_located函数定义,模拟显式等待
def wait_for_element_located(driver, by, value):
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((by, value)))
    return driver.find_element(by, value)

# 启动浏览器和打开网页的代码同上...

# 假定先要点击“精选联盟”的标题,尽管这可能不是直接使标题变为active的方式
# 但按照你的要求,先尝试点击
header_xpath = "//div[contains(@class, 'byte-tabs-header-title') and text()='精选联盟']"
header = wait_for_element_located(driver, By.XPATH, header_xpath)
if header:
    header.click()
    print("点击了精选联盟的标题")

    # 等待一段时间,模拟页面可能的反应时间
    time.sleep(2)

    # 尝试通过JS直接激活标题,这一步取决于页面实际逻辑,可能并不适用
    driver.execute_script("arguments[0].classList.add('active');", header)
    print("尝试通过JS使精选联盟标题变为active状态")

    # 接下来是定位并点击“添加更多”按钮的部分,保持原逻辑
    sell_good_button_xpath = "/html/body/div[4]/div[2]/div/div/div[2]/div[2]/div[1]/div/div/div/div[2]"
    sell_good_button = wait_for_element_located(driver, By.XPATH, sell_good_button_xpath)
    if sell_good_button:
        sell_good_button.click()
        print("点击了精选联盟的添加更多按钮")
        time.sleep(3)

# 记得在操作完成后关闭浏览器
# driver.quit()

<input placeholder="可输入商品或所属店铺" class="byte-input byte-input-size-default byte-input-suffix" value="《阿勒泰的角落》"> 模拟操作时,如何将value赋值 ?

在Selenium中,你可以通过定位到输入框元素,然后使用send_keys方法来模拟键盘输入,从而改变输入框的value。下面是针对你提供的HTML代码段的一个示例:

from selenium import webdriver
from selenium.webdriver.common.by import By

# 启动浏览器和打开网页的代码同上...

# 定位到输入框元素
input_box_xpath = "//input[@placeholder='可输入商品或所属店铺']"
input_element = driver.find_element(By.XPATH, input_box_xpath)

# 清除输入框已有内容(如果有的话)
input_element.clear()

# 输入新值
new_value = "你想要赋的新值"
input_element.send_keys(new_value)

# 打印确认信息
print(f"已将输入框的值设置为:{new_value}")

# 记得在操作完成后关闭浏览器
# driver.quit()

<div class="byte-radio-inner checked">如何实现。

from selenium import webdriver
from selenium.webdriver.common.by import By

# 启动浏览器和打开网页的代码同上...

# 定位到单选按钮的输入元素
# 注意,这里我们假设单选按钮是唯一的,或者你可以根据需要调整XPath以精确匹配
radio_button_xpath = "//div[@class='card-list-item commodity-card']//input[@type='radio']"
radio_button = driver.find_element(By.XPATH, radio_button_xpath)

# 点击单选按钮
radio_button.click()

# 打印确认信息
print("已尝试点击单选按钮")

# 如果需要,可以进一步检查是否选中,例如通过检查某个关联元素的class变化
# 这里假设点击后会有一个兄弟元素的class变为'checked'
check_mark_xpath = "//div[@class='card-list-item commodity-card']//span[@class='byte-radio-inner checked']"
try:
    check_mark = driver.find_element(By.XPATH, check_mark_xpath)
    print("单选按钮已被选中")
except Exception as e:
    print("未找到选中状态的标记,可能点击未生效或页面响应未完成")

# 记得在操作完成后关闭浏览器
# driver.quit()

 

还有很多。明天修改。今天在选择商品卡的一步,未选 中单选按钮。明天修改。

  • 45
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PyAIGCMaster

1毛钱也是爱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值