http请求入门和discord自动抽奖脚本

这段时间看到DFarm社区朋友有disocrd脚本的需求,包括抽奖机器人,消息监听,自动进群等等的功能,其实这些制作起来其实并不算困难

伟哥的文章写了discord脚本的原理,这些都涉及到基础的计算机网络知识

对于初学者来说,如果只懂语法而没有这方面的知识还是很难上手制作的。我就抛砖引玉,补充一下,也可以直接查看最后的discord自动抽奖代码

基础知识部分

什么是URL

URL 代表着是统一资源定位符(Uniform Resource Locator)。URL 无非就是一个给定的独特资源在 Web 上的地址。理论上说,每个有效的 URL 都指向一个唯一的资源。这个资源可以是一个 HTML 页面,一个 CSS 文档,一幅图像,等等。通俗的讲也就是告诉服务器你请求了什么内容

网页、服务器的请求的过程

Request (请求):每一个展示在用户面前的网页都必须经过这一步,也就是向服务器发送访问请求。

Response(响应):服务器在接收到用户的请求后,会验证请求的有效性,然后向用户(客户端)发送响应的内容,客户端接收服务器响应的内容,将内容展示出来,就是我们所熟悉的网页请求,如图1 所示

图1
图1

http的基本方法及其功能

对于用户这边的请求(Request)的发出,会有以下的几种方法

图2
图2

这个是做什么用的呢,其实表示的是你用不同的方法把你的信息发送给服务器。我们最常用的是get和post方法,但是discord也会用到其它的方法如put和delete,因为是根据restful风格设计的api,感兴趣的可以在下面的链接了解一下什么是restful风格

https://restfulapi.cn/

http的状态码和含义

对于服务器这边的响应(Response),当服务器接受到用户的请求,要做出回应,此网页所在的服务器会返回一个包含 HTTP 状态码的信息头(server header)用以响应浏览器的请求

每个状态码的含义具体可以看看以下链接

https://cloud.tencent.com/developer/article/1688459

关于HTTP还有一些更详细的内容可以查看菜鸟教程

https://www.runoob.com/http/http-messages.html

基础知识讲解完毕,接下来是实战部分(以discord抽奖机器人为例)

Discord实战部分

以下接口也可直接查看官方api文档获取,这里通过这种方式让大家了解discord的请求,演示使用edge浏览器,打开网页版disord,按下F12键选择选择网络(network),这里的每一行就是你对discord的请求和响应(图3)

图3
图3

点击红圈的按钮清除当前这些乱七八糟的请求,找一条信息点击表情(图4)

图4
图4

你会发现出现了一条新的信息%40me,点击查看(图5)

图5
图5

这里可以看到该请求使用的是put方法(图6)

图6
图6

图6圈出的三个位置,他们分别是频道id,消息id,和点击的表情(图7)

图7
图7
频道id:课程文章频道的id
消息id:《NFT第四课:获取Opensea的价格和属性》消息的id
表情:%F0%9F%8E%89

表情使用了URL加密,是为了符合URL的规则,在解密网站可以转换成:🎉符号

在请求头中可以看到有authorization这个参数,这个参数代表你的账号,每个人的账号是唯一的,也就是告诉服务器是谁做了点击表情这个动作,而且是一个put方法(图8)

图8
图8

分析完成我们可以构造脚本了

#点击表情
def clickEmoji(chanel_id,message_id,authorization,emoji):
    #请求头,带上你的authorization参数
    header = {
        "Authorization": authorization,
        "Content-Type": "application/json",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36"
    }
    # 按照我们看到的格式拼接频道的url
    url = 'https://discord.com/api/v9/channels/{}/messages/{}/reactions/{}/%40me'.format(chanel_id,message_id,emoji)
    # 通过put的方法发送
    res = requests.put(url=url, headers=header,proxies=proxies)
    print(res.content)

运行后就会自动点击对应的表情

为了制作抽奖机器人还需要获取频道信息的方法,下方是方法代码,他的三个参数分别为频道id,authorization,获取的消息条数,这也能用于聊天机器人的关键字检测

def get_context(chanel_id,authorization,num):
    headr = {
        "Authorization": authorization,#你的discord Authorization
        "Content-Type": "application/json",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36"
    }
    url = "https://discord.com/api/v9/channels/{}/messages?limit={}".format(chanel_id,num)
    res = requests.get(url=url, headers=headr, proxies=proxies)
    result = json.loads(res.content)
    return result

获取频道信息的接口+点击表情即可做出基本的自动抽奖功能了,主要流程是每5分钟查询一次频道最近的5条信息,获取有人点抽奖表情的消息id,然后点击消息的抽奖表情。

这段代码还是比较简单粗暴的,还有很多可以优化的地方,比如检测关键词,多线程等等。当然长时间,频繁运行discord脚本可能有封号风险,请酌情使用

import json
import time
import requests

#点击表情
def clickRaffle(chanel_id, messageid, emoji):
    # 拼接频道地址
    url = 'https://discord.com/api/v9/channels/{}/messages/{}/reactions/{}/%40me'.format(chanel_id, messageid, emoji)
    print(url)
    res = requests.put(url=url, headers=header,proxies=proxies)

#查找抽奖信息
def getRaffleInfo(chanel_id):
    url = "https://discord.com/api/v9/channels/{}/messages?limit=5".format(chanel_id)
    res = requests.get(url=url, headers=header, proxies=proxies)
    result = json.loads(res.content)
    message_list = []
    for res in result:
        try:
            print("{}:有点表情".format(res['id']))
            message_list.append(res['id'])
        except:
            print("{}:没有点表情".format(res['id']))
    return message_list


if __name__ == '__main__':
    proxies = {
        "http": "http://localhost:4780"
    }
    # 伪装头
    header = {
        #填入你的authorization
        "Authorization": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        "Content-Type": "application/json",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36"
    }
    while True:
        chanel_id = 888888888888888888888 #需要监控的频道
        emoji = "%F0%9F%8E%89"#需要点击的表情
        message_list = getRaffleInfo(chanel_id)
        for messageid in message_list:
            time.sleep(2)
            clickRaffle(chanel_id, messageid, emoji)
        print("本轮监听结束,等待5分钟后再次监听")
        time.sleep(300)

来自DFarm Club