Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >爬虫进阶教程:爬虫进阶教程:百万英雄答题辅助系统

爬虫进阶教程:爬虫进阶教程:百万英雄答题辅助系统

作者头像
圆方圆PYTHON学院
修改于 2019-01-15 08:45:49
修改于 2019-01-15 08:45:49
1.3K0
举报
文章被收录于专栏:Python学习心得Python学习心得

原文链接及原作者:爬虫进阶教程:百万英雄答题辅助系统 | Jack Cui

0.png
0.png

一、前言

看了网上很多的教程都是通过OCR识别的,这种方法的优点在于通用性强。不同的答题活动都可以参加,但是缺点也明显,速度有限,并且如果通过调用第三方OCR,有次数限制。但是使用本教程提到的数据接口。我们能很容易的获取数据,速度快,但是接口是变化的,需要及时更新。

二、实战解析

1、背景介绍

1.jpg
1.jpg

百万英雄答题是一个最近很火爆的答题软件,答对12题的人,可以平分最后的奖金。奖金不错,笔者参加过几次,不过获得的都是小奖,最后几块钱的那种。对于不难的题目,能够直接百度出答案的题目,如果有个软件辅助实时给出参考,还是一件很舒服的事情。想干就干,走起!

2、先睹为快

先看下部署效果,通过服务器后端处理,通过前端显示,亲测延时3s:

2 (2).gif
2 (2).gif

为啥做成这样呢?因为这样,别的人也可以通过浏览器进行访问,独乐不如众乐嘛!

Github开源地址:https://github.com/Jack-Cherish/python-spider

3、西瓜视频APP抓包

对于如何抓包,我想应该都会了,我在手机APP抓包教程中有详细讲解,如有不会的,请暂时移步:Python3网络爬虫(十三):王者荣耀那些事!(Fiddler之手机APP爬取)

在比赛答题的时候,我们可以通过抓包,找到这样的接口(点击放大):

3.jpg
3.jpg

可以看到,参数如上图所示。其中heartbeat后面的参数是一个随着场次的增加,逐渐增加的一个数,后面其他的例如iid和device_id是每个人的用户信息,在接口的最后,有个rticket参数,这个是一个时间戳,可以通过time.time()模拟。

2018-1-17更新:据朋友反应,url的有效参数只有heartbeat和rticket参数,用户信息可以不填写。

注意:只有在答题直播开始的时候,才能通过接口抓取到数据,没有直播的时候,是获取不到数据的,是乱码。

通过这个接口获取数据,然后对数据进行解析,在通过百度知道索问题,简单高效。有了这个思想,就可以开始写代码了。

代码语言:txt
AI代码解释
复制
# -*-coding:utf-8 -*-
import requests
from lxml import etree
from bs4 import BeautifulSoup
import urllib
import time, re, types, os
 
 
"""
代码写的匆忙,本来想再重构下,完善好注释再发,但是比较忙,想想算了,所以自行完善吧!写法很不规范,勿见怪。
作者:  Jack Cui
Website:https://cuijiahua.com
注:     本软件仅用于学习交流,请勿用于任何商业用途!
"""
 
class BaiWan():
    def __init__(self):
        # 百度知道搜索接口
        self.baidu = 'http://zhidao.baidu.com/search?'
        # 百万英雄及接口,每个人的接口都不一样,里面包含的手机信息,因此不公布,请自行抓包,有疑问欢迎留言:https://cuijiahua.com/liuyan.html
        self.api = 'https://api-spe-ttl.ixigua.com/xxxxxxx={}'.format(int(time.time()*1000))
 
    # 获取答案并解析问题
    def get_question(self):
        to = True
        while to:
            list_dir = os.listdir('./')
            if 'question.txt' not in list_dir:
                fw = open('question.txt', 'w')
                fw.write('百万英雄尚未出题请稍后!')
                fw.close()        
            go = True
            while go:
                req = requests.get(self.api, verify=False)
                req.encoding = 'utf-8'
                html = req.text
 
                print(html)
                if '*' in html:
                    question_start = html.index('*')
                    try:
                        
                        question_end = html.index('?')
                    except:
                        question_end = html.index('?')
                    question = html[question_start:question_end][2:]
                    if question != None:
                        fr = open('question.txt', 'r')
                        text = fr.readline()
                        fr.close()
                        if text != question:
                            print(question)
                            go = False
                            with open('question.txt', 'w') as f:
                                f.write(question)
                        else:
                            time.sleep(1)
                    else:
                        to = False
                else:
                    to = False
 
            temp = re.findall(r'[\u4e00-\u9fa5a-zA-Z0-9\+\-\*/]', html[question_end+1:])
            b_index = []
            print(temp)
 
            for index, each in enumerate(temp):
                if each == 'B':
                    b_index.append(index)
                elif each == 'P' and (len(temp) - index) <= 3 :
                    b_index.append(index)
                    break
 
            if len(b_index) == 4:
                a = ''.join(temp[b_index[0] + 1:b_index[1]])
                b = ''.join(temp[b_index[1] + 1:b_index[2]])
                c = ''.join(temp[b_index[2] + 1:b_index[3]])
                alternative_answers = [a,b,c]
 
                if '下列' in question:
                    question = a + ' ' + b + ' ' + c + ' ' + question.replace('下列', '')
                elif '以下' in question:
                    question = a + ' ' + b + ' ' + c + ' ' + question.replace('以下', '')
            else:
                alternative_answers = []
            # 根据问题和备选答案搜索答案
            self.search(question, alternative_answers)
            time.sleep(1)
 
    def search(self, question, alternative_answers):
        print(question)
        print(alternative_answers)
        infos = {"word":question}
        # 调用百度接口
        url = self.baidu + 'lm=0&rn=10&pn=0&fr=search&ie=gbk&' + urllib.parse.urlencode(infos, encoding='GB2312')
        print(url)
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36',
        }
        sess = requests.Session()
        req = sess.get(url = url, headers=headers, verify=False)
        req.encoding = 'gbk'
        # print(req.text)
        bf = BeautifulSoup(req.text, 'lxml')
        answers = bf.find_all('dd',class_='dd answer')
        for answer in answers:
            print(answer.text)
 
        # 推荐答案
        recommend = ''
        if alternative_answers != []:
            best = []
            print('\n')
            for answer in answers:
                # print(answer.text)
                for each_answer in alternative_answers:
                    if each_answer in answer.text:
                        best.append(each_answer)
                        print(each_answer,end=' ')
                        # print(answer.text)
                        print('\n')
                        break
            statistics = {}
            for each in best:
                if each not in statistics.keys():
                    statistics[each] = 1
                else:
                    statistics[each] += 1
            errors = ['没有', '不是', '不对', '不正确','错误','不包括','不包含','不在','错']
            error_list = list(map(lambda x: x in question, errors))
            print(error_list)
            if sum(error_list) >= 1:
                for each_answer in alternative_answers:
                    if each_answer not in statistics.items():
                        recommend = each_answer
                        print('推荐答案:', recommend)
                        break
            elif statistics != {}:
                recommend = sorted(statistics.items(), key=lambda e:e[1], reverse=True)[0][0]
                print('推荐答案:', recommend)
 
        # 写入文件
        with open('file.txt', 'w') as f:
            f.write('问题:' + question)
            f.write('\n')
            f.write('*' * 50)
            f.write('\n')
            if alternative_answers != []:
                f.write('选项:')
                for i in range(len(alternative_answers)):
                    f.write(alternative_answers[i])
                    f.write('  ')
            f.write('\n')
            f.write('*' * 50)
            f.write('\n')
            f.write('参考答案:\n')
            for answer in answers:
                f.write(answer.text)
                f.write('\n')
            f.write('*' * 50)
            f.write('\n')
            if recommend != '':
                f.write('最终答案请自行斟酌!\t')
                f.write('推荐答案:' + sorted(statistics.items(), key=lambda e:e[1], reverse=True)[0][0])
 
 
if __name__ == '__main__':
    bw = BaiWan()
    bw.get_question()

获取数据和查找答案就是这样,很简单,代码写的也较为凌乱,大牛可以按照这个思路改一改。

4、网站部署

没做过后端和前端,花了一天时间,现学现卖弄好的,javascript也是现看现用,百度的程序,调试调试而已。可能有很多用法比较low的地方,用法不对,请勿见怪,有大牛感兴趣,可以自行完善。

这是我当时看的一些文章:

Node.js和Socket.IO通信基础:菜鸟学习nodejs--Socket.IO即时通讯

Node.js逐行读取txt文件:Line-Reader

Node.js定时任务:Node-Schedule

后端app.js:

代码语言:txt
AI代码解释
复制
ar http = require('http');
var fs = require('fs');
var schedule = require("node-schedule"); 
var message = {};
var count = 0;
var server = http.createServer(function (req,res){
    fs.readFile('./index.html',function(error,data){
        res.writeHead(200,{'Content-Type':'text/html'});
        res.end(data,'utf-8');
    });
}).listen(80);
console.log('Server running!');
var lineReader = require('line-reader');
function messageGet(){
    lineReader.eachLine('file.txt', function(line, last) {
        count++;
        var name = 'line' + count;
        console.log(name);
    console.log(line);
        message[name] = line;
    });  
    if(count == 25){
        count = 0;
    }
    else{
        for(var i = count+1; i <= 25; i++){
          var name = 'line' + i;
            message[name] = 'f';
    }
      count = 0;
    }
}
var io = require('socket.io').listen(server);
var rule = new schedule.RecurrenceRule();
var times = [];
for(var i=1; i<1800; i++){
    times.push(i);
}
rule.second = times;
schedule.scheduleJob(rule, function(){
        messageGet();
});
io.sockets.on('connection',function(socket){
       // console.log('User connected' + count + 'user(s) present');
        socket.emit('users',message);
        socket.broadcast.emit('users',message);
 
    socket.on('disconnect',function(){
        console.log('User disconnected');
        //socket.broadcast.emit('users',message);  
    });
});

前端index.html:

代码语言:txt
AI代码解释
复制
!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="refresh" content="2">
    <title>Jack Cui答题辅助系统</title>
  </head>
  <body>
    <h1>百万英雄答题辅助系统</h1>
    <p id="line1"></p>
    <p id="line2"></p>
    <p id="line3"></p>
    <p id="line4"></p>
    <p id="line5"></p>
    <p id="line6"></p>
    <p id="line7"></p>
    <p id="line8"></p>
    <p id="line9"></p>
    <p id="line10"></p>
    <p id="line11"></p>
    <p id="line12"></p>
    <p id="line13"></p>
    <p id="line14"></p>
    <p id="line15"></p>
    <p id="line16"></p>
    <p id="line17"></p>
    <p id="line18"></p>
    <p id="line19"></p>
    <p id="line20"></p>
    <p id="line21"></p>
    <p id="line22"></p>
    <p id="line23"></p>
    <p id="line24"></p>
    <p id="line25"></p>
    <script src="https://222.222.124.77:9001/jquery.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    <script>
      var socket = io.connect('http://你的IP:端口');
      var line1 = document.getElementById('line1');
      var line2 = document.getElementById('line2');
      var line3 = document.getElementById('line3');
      var line4 = document.getElementById('line4');
      var line5 = document.getElementById('line5');
      var line6 = document.getElementById('line6');
      var line7 = document.getElementById('line7');
      var line8 = document.getElementById('line8');
      var line9 = document.getElementById('line9');
      var line10 = document.getElementById('line10');
      var line11 = document.getElementById('line11');
      var line12 = document.getElementById('line12');
      var line13 = document.getElementById('line13');
      var line14 = document.getElementById('line14');
      var line15 = document.getElementById('line15');
      var line16 = document.getElementById('line16');
      var line17 = document.getElementById('line17');
      var line18 = document.getElementById('line18');
      var line19 = document.getElementById('line19');
      var line20 = document.getElementById('line20');
      var line21 = document.getElementById('line21');
      var line22 = document.getElementById('line22');
      var line23 = document.getElementById('line23');
      var line24 = document.getElementById('line24');
      var line25 = document.getElementById('line25');
      socket.on('users',function(data){
        if(data.line1 == 'f'){
           line1.innerHTML = '' 
        }
        else{
           line1.innerHTML = data.line1
        }
        if(data.line2 == 'f'){
           line2.innerHTML = '' 
        }
        else{
           line2.innerHTML = data.line2
        }
        if(data.line3 == 'f'){
           line3.innerHTML = '' 
        }
        else{
           line3.innerHTML = data.line3
        }
        if(data.line4 == 'f'){
           line4.innerHTML = '' 
        }
        else{
           line4.innerHTML = data.line4
        }
        if(data.line5 == 'f'){
           line5.innerHTML = '' 
        }
        else{
           line5.innerHTML = data.line5
        }
        if(data.line6 == 'f'){
           line6.innerHTML = '' 
        }
        else{
           line6.innerHTML = data.line6
        }
        if(data.line7 == 'f'){
           line7.innerHTML = ''
        }
        else{
           line7.innerHTML = data.line7
        }
        if(data.line8 == 'f'){
           line8.innerHTML = '' 
        }
        else{
           line8.innerHTML = data.line8
        }
        if(data.line9 == 'f'){
           line9.innerHTML = '' 
        }
        else{
           line9.innerHTML = data.line9
        }
        if(data.line10 == 'f'){
           line10.innerHTML = '' 
        }
        else{
           line10.innerHTML = data.line10
        }
        if(data.line11 == 'f'){
           line11.innerHTML = '' 
        }
        else{
           line11.innerHTML = data.line11
        }
        if(data.line12 == 'f'){
           line12.innerHTML = '' 
        }
        else{
           line12.innerHTML = data.line12
        }
        if(data.line13 == 'f'){
           line13.innerHTML = '' 
        }
        else{
           line13.innerHTML = data.line13
        }
        if(data.line14 == 'f'){
           line14.innerHTML = '' 
        }
        else{
           line14.innerHTML = data.line14
        }
        if(data.line15 == 'f'){
           line15.innerHTML = '' 
        }
        else{
           line15.innerHTML = data.line15
        }
        if(data.line16 == 'f'){
           line16.innerHTML = ''
        }
        else{
           line16.innerHTML = data.line16
        }
        if(data.line17 == 'f'){
           line17.innerHTML = '' 
        }
        else{
           line17.innerHTML = data.line17
        }
        if(data.line18 == 'f'){
           line18.innerHTML = '' 
        }
        else{
           line18.innerHTML = data.line18
        }
        if(data.line19 == 'f'){
           line19.innerHTML = '' 
        }
        else{
           line19.innerHTML = data.line19
        }
        if(data.line20 == 'f'){
           line20.innerHTML = '' 
        }
        else{
           line20.innerHTML = data.line20
        }
        if(data.line21 == 'f'){
           line21.innerHTML = '' 
        }
        else{
           line21.innerHTML = data.line21
        }
        if(data.line22 == 'f'){
           line22.innerHTML = '' 
        }
        else{
           line22.innerHTML = data.line22
        }
        if(data.line23 == 'f'){
           line23.innerHTML = '' 
        }
        else{
           line23.innerHTML = data.line23
        }
        if(data.line24 == 'f'){
           line24.innerHTML = ''
        }
        else{
           line24.innerHTML = data.line24
        }
        if(data.line25 == 'f'){
           line25.innerHTML = '' 
        }
        else{
           line25.innerHTML = data.line25
        }
      });
    </script>
 
  </body>
</html>

将这些部署到服务器上。这是我的部署效果:

4.jpg
4.jpg

部署好后。使用指令运行Node.js服务:

node app.js

运行python3脚本:

python3 baiwan.py

如果一切都搭建好了,那么这个百万英雄答题辅助系统就可以运行了!

三、总结

  • 本软件仅用于学习交流,请勿用于任何商业用途。
  • 也可以对代码进行简单修改,python打印信息,只在本地查看,无需写入txt文件,部署到服务器上。
  • 代码乱,没有经过优化,还需重构。
  • 我的Github爬虫开源地址:https://github.com/Jack-Cherish/python-spider/

相关文章和视频推荐

圆方圆学院汇集 Python + AI 名师,打造精品的 Python + AI 技术课程。 在各大平台都长期有优质免费公开课及录像,欢迎报名收看。

公开课地址:https://ke.qq.com/course/362788?flowToken=1007319

加入python学习讨论群 78486745 ,获取资料,和广大群友一起学习。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【董天一】IPFS如何挖矿<Filecoin系统>?(一)
本来这篇文章应该晚一点写, 但是这几天一直有朋友在公众号留言, 迫切的想知道IPFS到底如何挖矿, 所以就提前写一篇关于IPFS挖矿的文章. 本文暂不涉及具体的技术细节, 只做大概的介绍.
圆方圆学院
2018/11/12
1K0
【董天一】IPFS如何挖矿<Filecoin系统>?(一)
【董天一】IPFS的竞争对手们(一)
        IPFS这个项目真的开发很慢,相比其它区块链项目,IPFS的进度可真是让小编捉急,恨铁不成钢啊。然而小编仍然对他们充满信心,来,借用一句盗梦空间里的经典台词:
圆方圆学院
2018/11/12
1.4K0
【董天一】IPFS和竞争对手们(二)
在上一篇《IPFS和竞争对手们(一)》的开头抱怨的IPFS的开发进度,今天才得知 MaidSafe 是从2006年起步的,这进度也是醉了。
圆方圆学院
2018/11/12
8790
【董天一】Filecoin: 影响力容错(PFT)和预期共识(EC)
这是filecoin协议里面对 PFT的解释,power概念就是矿工的影响力(influence),“Power”是filecoin系统的投票权力的大小度量,根据矿工贡献的Power来计算矿工的投票权有多大,根据信达雅的基本要求,所以称为“影响力容错”。之前曾经考虑过“权利容错”和“权益容错”,“权利”这个词本身表达不了大小的概念,而“权益”又跟Proof of Stake(权益证明:EC共识是在这个基础上进行的,有必要区分)有冲突,于是小编把这个词翻译成影响力容错。或许有更贴切的表达方式,欢迎讨论!
圆方圆学院
2018/11/12
8570
【董天一】Filecoin: 影响力容错(PFT)和预期共识(EC)
【董天一】IPFS vs Filecoin: 开发者该如何选择
小编最近经常接到一些开发者的咨询,我想用IPFS来做开发,该怎么提供解决方案(特别是对于区块链项目)那么今天我们就来说一下开发者面对IPFS和Filecoin的时候该如何选择
圆方圆学院
2018/11/12
8390
【董天一】IPFS vs Filecoin: 开发者该如何选择
【董天一】Filecoin: 矿工是怎么赚取FIL的
前提:矿工既可以单独参与检索矿工,也可以单独参与存储矿工。但是小编觉得,一起参与才是正道
圆方圆学院
2019/03/14
7910
【董天一】Filecoin: 矿工是怎么赚取FIL的
【董天一】IPFS:Filecoin和复制证明
这篇文章主要来讲一下Filecoin协议里面的复制证明(Proof of Replication),由于协议涉及到很多概念,可能看起来有点晕乎乎的,小编尽量把复杂问题简单化 ,力求给大家做大普及IPFS知识
圆方圆学院
2018/11/12
1.2K0
【董天一】IPFS:Filecoin和复制证明
笼罩在Filecoin上空的三朵乌云
Filecoin测试网络上线近4个月,经历第一阶段、互操作阶段,即将进入第二阶段,主网预计会在7月左右上线。Filecoin的大厦看似即将落成,所剩的只是一些修饰工作。
用户9624935
2022/04/02
3880
笼罩在Filecoin上空的三朵乌云
【董天一】Filecoin协议(挖矿)
        首先上一张图,图片来自于Filecon论文的截图。这上面涉及到很多技术,如果看不懂没关系,小编慢慢给大家讲解:
圆方圆学院
2018/11/12
7040
Filecoin的过去、现在和未来
Filecoin网络是在互联网架构变革的中期推出的。在这场变革中,脆弱的中心化服务(依赖于受信任方),正在被基于可验证计算的弹性去中心化解决方案所取代。互联网服务正在从低效的中心化单体服务转移到网络的边缘,这其中的推手是正在崛起的p2p市场。
用户9624935
2022/04/02
7100
Filecoin的过去、现在和未来
海豚扒问IPFS中国区布道人董天一:IPFS为什么可以超越HTTP
亲爱的粉丝们,今天又到了【海豚扒问】的深扒时间啦。萌主我一直很感谢大家一路对海豚区块链全新推出的【海豚扒问】栏目的支持,这一次我们请来最重量的嘉宾,他是谁?他为什么是我们海豚区块链如此仰慕,甚至需要深深膜拜的嘉宾?待萌主用一句诗句来形容他的气质以及为他这个行业做出的贡献。“桐花万里丹山路,雏凤清于老凤声”,这句诗出自李商隐,它正如董老师一样,朝气蓬勃,是勇于探索这个时代伟大的先知。他不是宋冬野歌里所唱的“董小姐”,他是董天一,IPFS/Filecoin中国区技术布道人,更是万卷诗书里《IPFS指南》的作者。他是北大才子,毕业于北京大学软件与微电子学院,并且曾担任甲骨文亚洲研发中心(中国)数据库开发工程师,是资深的区块链技术开发者,现致力于IPFS/Filecoin在中国的技术推广。他的出现启发了很多人,更启发了正在创业的小海豚。他对技术的痴迷,对新鲜事物无止境的探索,以及开拓新鲜事物却永不畏惧的精神,深深的影响着我。那么今天不再做铺垫了,现在我们以最原汁原味的方式来感受紧张的海豚与董老师的对话。
海豚区块链
2018/05/17
1K0
海豚扒问IPFS中国区布道人董天一:IPFS为什么可以超越HTTP
【董天一】Filecoin:募资详情和Token分发详情
    vesting period: 原先被小编翻译成了“锁定期”,这对于filecoin是不准确的,可能误导了一些读者,在这里给大家致歉。
圆方圆学院
2019/03/14
1.1K0
【董天一】Filecoin:募资详情和Token分发详情
【董天一】什么是IPFS?(三)
上面的应用场景是 IPFS的创始人 Juan Benet 在IPFS论文里面直接提到的. 有兴趣的同学可以去IPFS白皮书里面看一下。
圆方圆学院
2018/11/12
1K0
【董天一】什么是IPFS?(三)
【董天一】什么是IPFS?(一)
写在前面: 今天先写到这里,关于IPFS的所有事情小编都想快点告诉大家,但毕竟精力有限,小编尽量抽出时间提供更多的关于IPFS的信息。
圆方圆学院
2018/11/12
1.1K0
【董天一】什么是IPFS?(一)
【董天一】关于IPFS的热门问题
        目前网络上有一些对ipfs的解读五花八门,各式各样,有看好的,也有打击的,总之一项新技术诞生之初遇到的问题IPFS都遇到了。
圆方圆学院
2018/11/12
1K0
【董天一】关于IPFS的热门问题
Filecoin全球公测的意义
美西时间2019年12月11日,中国时间12月12日,Filecoin测试网上线。我参与了部分测试网的一些测试工作,期间有一些不成熟的思考,总结下来,与诸君分享。
用户9624935
2022/04/02
4720
Filecoin全球公测的意义
【董天一】Filecoin2017年Q4进度更新(完整版)
自从Token销售完成以后,我们便开始集中精力把Filecoin项目从设想变为现实-从实现Filecoin协议的核心代码到打造我们优秀的团队。下面是来自于我们团队的进度更新,以及一些我们期望您和社区来参与的工作。
圆方圆学院
2019/03/14
5050
【董天一】Filecoin2017年Q4进度更新(完整版)
【董天一】一场IPFS引领下的共享之风正在走向区块链
中国互联网的高速发展 已经接近10年,小编完整的经历这个过程。这一切我们从一个小网站 饭否 说起。。。
圆方圆学院
2018/11/12
5720
【董天一】IPFS:世界正在悄然发生变化
        2015-05-05 Juan Benet 在自己的终端里面敲入了下面的文字:
圆方圆学院
2018/11/12
9690
【董天一】IPFS:世界正在悄然发生变化
为什么说IPFS和Filecoin是构建Web3的基石?
之前我编译了一篇文章:《Web3的三次革命》,介绍Web3的发展历程以及历史钟摆的趋势。这篇文章被大量自媒体转载,并产生了上万的阅读量。鉴于疫情的原因和互联网的内卷化发展,Web3越来越受到人们的关注。那么Web3到底是什么?为什么说IPFS和Filecoin是构建Web3的重要基石?
用户9624935
2022/04/02
4980
为什么说IPFS和Filecoin是构建Web3的基石?
相关推荐
【董天一】IPFS如何挖矿<Filecoin系统>?(一)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档