coze 工作流微博关键词爬虫

目录

效果预览

微博api

工作流搭建


效果预览

用扣子平台通过工作流的方式搭建了微博关键词爬虫,通过对话方式,效果如下:

调用的是微博官方的 api 接口,有一定限制,不适合大量爬取,适合场景为想要快速根据词条获得一些评论数据进行分析的人使用。

所以可以通过工作流方式进行封装,主要是把爬虫代码封装进工作流。

微博api

API - 微博API

爬虫用到的 api,因为需要登录才能获得数据,且扣子不支持把以下代码封装,所以我们我们需要用自己微博账号注册一个应用获得 app key,app secret,参考链接:

爬取微博热搜评论生成词云

获得后使用 python 运行以下代码,

client_key = '你的 app key',

client_secret = '你的 app secret'

记得替换为你自己的,其他不用任何修改

python 复制代码
import json
import requests
import webbrowser
import time

def get_access_token():
    # 授权步骤
    # https://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E#.E5.BA.94.E7.94.A8.E5.9C.BA.E6.99.AF

    # 第一步 authorize 接口,请求用户授权code
    # https://open.weibo.com/wiki/Oauth2/authorize
    client_key = '你的 app key'
    redirect_uri = 'https://api.weibo.com/oauth2/default.html'
    url1 = 'https://api.weibo.com/oauth2/authorize'
    res_1 = requests.get(url1, params={'client_id': client_key, 'redirect_uri': redirect_uri})
    webbrowser.open_new(res_1.url)
    code = input('输入 code:')

    # 第二步 access_token 接口,用 code 换取授权 access_token
    # https://open.weibo.com/wiki/Oauth2/access_token
    client_secret = '你的 app secret'
    url2 = 'https://api.weibo.com/oauth2/access_token'
    res_2 = requests.post(url2, data={
        'client_id': client_key, 'client_secret': client_secret, 'redirect_uri': redirect_uri,
        'grant_type': 'authorization_code', 'code': code})
    data = res_2.json()
    access_token = data['access_token']
    expires_in = data['expires_in']
    print(f'token:{access_token}, 有效时间:{expires_in}s')

    # 获取当前时间戳(以秒为单位)
    current_timestamp = int(time.time())
    # 计算过期时间戳
    expiration_timestamp = current_timestamp + expires_in

    # 保存
    data['expiration_timestamp'] = expiration_timestamp
    with open('access_token.json', 'w') as f:
        f.write(json.dumps(data, ensure_ascii=False))

    return access_token

print(get_access_token())

运行后会在打开浏览器,你需要用微博扫码登录后会变成以下页面,输入这个 code 会得到结果 json 文件:

代码同目录获得 access_token.json 文件:

这是我们需要上传到工作流的凭证。

工作流搭建

打开扣子,新建项目,选择对话流模式,设置开场白:

添加对话流,即新建对话流,开始节点不用动,添加一个代码节点,用来分割用户输入的关键词及 token 文件链接,输入引用用户的输入,输出添加 ret 变量中的字段:

python 复制代码
async def main(args: Args) -> Output:
    params = args.params
    # 构建输出对象
    ret: Output = {
        "word": params['input'].split(',')[0],
        "url": params['input'].split(',')[-1]
    }
    return ret

添加插件节点"读取上传的token文件",输入引用代码分割后的 url,此 url 是用户上传后 token 的 url,也就是读取文件内容的插件,这里读 token

根据此条构造爬取页数获取微博id,也是一个代码节点,爬虫代码的一部分,输入引用代码分割后得到的词条,输出爬取得到微博 ids:

python 复制代码
import requests_async as requests
import json

async def main(args: Args) -> Output:
    params = args.params
    word = params['word']
    urls = ['https://m.weibo.cn/api/container/getIndex?containerid=100103type%3D1%26q%3D{}&page_type=searchall&page={}'
            .format(word, i) for i in range(1, 51)]
    headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',
    }
    
    async def get_ids(urls):
        # 获取多页 id
        ids = []
        for index, url in enumerate(urls):
            print(f'当前页数 {index + 1}/{len(urls)}........')
            response = await requests.get(url, headers=headers)
            data = json.loads(response.text)
            cards = data['data']['cards']
            for d in cards:
                try:
                    id_ = d['mblog']['id']
                except KeyError:
                    try:
                        id_ = d['card_group'][0]['mblog']['id']
                    except KeyError:
                        id_ = ''
                if id_ != '':
                    ids.append(id_)
        print(f'总共 {len(ids)} 条微博.')
        return ids

    ids = await get_ids(urls)
    # 构建输出对象
    ret: Output = {
        "ids": ids[:1]
    }
    return ret

数据用飞书电子表格保存,所以添加两个插件节点,一个是创建表格,一个是写入表格;

创建表格的名称引用代码分割的词条:

根据微博id爬取评论,也是一个代码节点,输入引用读取获得的 token,以及爬取得到的微博ids,输出爬取得到的评论列表及长度:

python 复制代码
import json
import requests_async as requests


async def main(args: Args) -> Output:
    params = args.params
    ids = params['ids']
    access_token = json.loads(params['access_token'])['access_token']

    comment_text_list_s = [['评论创建时间', '评论的ID', '评论的内容', '评论用户']]
    for index, _id in enumerate(ids):
        created_at_lst = []  # 保存所有评论创建时间
        id_lst = []  # 保存所有评论的 id
        text_lst = []  # 保存所有评论的 text
        user_lst = []  # 保存所有评论的 user 信息
        user_name_lst = []  # 保存所有评论的 user 名称
        mid_lst = []  # 保存所有评论的 mid
        idstr_lst = []  # 保存所有评论的字符串 id
        status_lst = []  # 保存所有评论的微博信息
        reply_comment_lst = []  # 保存所有评论来源评论,当本评论属于对另一评论的回复时返回此字段

        # 共获取 2 页 * 每页最多 100 条评论
        flag = 0
        for i in range(1, 3):
            url = 'https://api.weibo.com/2/comments/show.json'
            result = await requests.get(url, params={'access_token': access_token, 'id': _id, 'count': 100})

            # 判断是否被限流
            if json.loads(result.text).get('error') is not None:
                print(f'可能被限流了,{result.text}')
                exit(0)

            comments = json.loads(result.text)['comments']
            if not len(comments):
                break

            for item in comments:
                created_at = item['created_at']
                comment_id = item['id']
                text = item['text']
                user = item['user']
                user_name = user['name']
                mid = item['mid']
                idstr = item['idstr']
                status = item['status']
                reply_comment = item.get('reply_comment')

                # 判断时候评论开始重复
                if idstr in idstr_lst:
                    print(f'当前页数 {i} 评论重复,跳过')
                    flag = 1
                    break

                created_at_lst.append(str(created_at))
                id_lst.append(str(comment_id))
                text_lst.append(str(text))
                user_lst.append(str(user))
                user_name_lst.append(str(user_name))
                mid_lst.append(str(mid))
                idstr_lst.append(str(idstr))
                status_lst.append(str(status))
                reply_comment_lst.append(str(reply_comment))

            if flag:
                break

        # comment_text_list = list(zip(created_at_lst, id_lst, text_lst, user_lst, user_name_lst, mid_lst,
        #                             idstr_lst, status_lst, reply_comment_lst))
        comment_text_list = list(zip(created_at_lst, id_lst, text_lst, user_name_lst))
        comment_text_list_s.extend(comment_text_list)

    comment_text_list_s = comment_text_list_s
    comment_text_list_s = [list(i) for i in comment_text_list_s]
    # records = []
    # for c in comment_text_list_s:
    #     f = {
    #             "评论创建时间": c[0],
    #             "评论的ID": c[1],
    #             "评论的内容": c[2],
    #             "评论的点赞数": c[3],
    #             "评论用户": c[4],
    #             "评论用户ID": c[5],
    #             "字符串型的评论ID": c[6],
    #             "评论的微博信息": c[7],
    #             "评论来源评论": c[8]
    #         }
    #     records.append({
    #         "fields": str(f)
    #     })
    # 构建输出对象
    ret: Output = {
        "comments": str(comment_text_list_s).replace("'", '"'),
        "len": len(comment_text_list_s),
        # "records": records
    }
    return ret

写入数据到表格,输入引用如下图:

结束节点,就输出回复,飞书表格链接,要从后 200 行开始看:

对话流配置好发布,在刚开始项目中添加即可完成了

相关推荐
数据小小爬虫14 分钟前
如何利用Python爬虫按图搜索1688商品(拍立淘):实战指南
爬虫·python·图搜索算法
小爬虫程序猿7 小时前
利用Python爬虫按图搜索1688商品(拍立淘):实战指南
爬虫·python·图搜索算法
数据小小爬虫7 小时前
利用Python爬虫按图搜索1688商品(拍立淘)
爬虫·python·图搜索算法
Anchenry11 小时前
【Python爬虫】爬取公共交通路网数据
开发语言·爬虫·python
以德服人231 天前
自学嵌入式第27天------TCP和UDP,URL爬虫
爬虫·tcp/ip·udp
B站计算机毕业设计超人1 天前
计算机毕业设计Python小说推荐系统 K-means聚类推荐算法 深度学习 Kears 小说数据分析 可视化 Scrapy爬虫 协同过滤
爬虫·python·深度学习·机器学习·毕业设计·数据可视化·推荐算法
小白学大数据1 天前
Ruby爬虫如何控制并发数量:爬取京东电子产品
大数据·开发语言·网络·爬虫·python·ruby
web150854159351 天前
基于python的网络爬虫爬取天气数据及可视化分析(Matplotlib、sk-learn等,包括ppt,视频)
爬虫·python·matplotlib
m0_748240912 天前
Vllm进行Qwen2-vl部署(包含单卡多卡部署及爬虫请求)
爬虫