用Python抓取各交易所公告,并筛选对你有用的内容

2019-04-07  本文已影响0人  杨卫祥_老杨提醒

我们经常会遇到这种情况,需要关注各个交易所的公告,并且找出自己感兴趣的内容。比如最近IEO比较火,需要关注币安的Launchpad, 火币的Prime, OK的Jumpstart,比特儿的GT售卖等等,一个个翻交易所公告还挺多;再比如我对币圈的各种活动、交易赛感兴趣,需要经常翻看公告,那么多交易所,每天光看这个就很占时间。

那有没有一种办法用程序快速查找各交易所公告,并筛选对你有用的内容呢?这是我最近非常想做的,因为python没学多久,今天终于花了近一天的时间,搞定了。

首先要感谢CSDN网站作者思无涯520的两篇文章,我是按照他的思路来做的:

Python爬虫之爬取静态网站——爬取各大币交易网站公告(一) 

Python爬虫之爬取动态网站——爬取各大币交易网站公告(二)

我按照他的教程一学会了静态网站的抓取,也是ZB交易所;

接下来又按照教程二制抓取动态网站币虎Cointiger的公告,发现问题,只能获取一条英文的公告,因网站改版改各种参数也无效。

后来想想,我关注的至少有几十个交易所,如果这样一个个搞下去,要累死个人啊,有没有简便的办法?

我当时想到一点,在两个网站上有集成的交易所公告,就是汇集了各个交易所的公告,一个是非小号,一个是MyToken,如果我把这两个抓取成功,那不就是以一抵百了嘛!

因为非小号最近改版,导致不少交易所还没有入驻,公告当然也没有,我就先从MyToken下手。

Python版本:Python3.X

运行平台:MAC

IDE:PyCharm

浏览器:Chrome

网站:MyToken,非小号等。此处以MyToken为例。

(一)分析网站

查看https://www.mytoken.io/announcement/的网页源代码(Chrome—视图—开发者—显示源代码),无法在HTML中找到对应公告信息,判断为动态网站,许多数据并不是写死在HTML中,而是通过js动态载入的,是在页面加载到浏览器后动态生成的。否则可以直接在网页源代码找到显示公告的内容为静态网站。

在Chrome浏览器中,点击F12,打开Network中的XHR,我们来抓取对应的js文件来进行解析。如下图:

刷新页面,我们看到以下界面:通过查找发现Medialist那里与我们想要的相关,点击展开得到:

为了获取这些信息,点击Headers,获得我们要抓取的访问条件:

我们得到了Requests Header的请求参数。page:1那里指第一页。

(二)通过requests模块发送请求数据如下

headers = {

   'User - Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',

   'Referer':'https://www.mytoken.io/announcement/'

target ='https://speed-api.mytokenapi.com/media/medialist?type=6&keyword=exchange_announcement&need_pagination=1&page=1&size=20&timestamp=1554598192915&code=028029243b91d813e6c35a5d5d259a4f&platform=web_pc&v=1.0.0&language=zh_CN&legal_currency=CNY'  #此为Request URL

req = requests.get(url=target,headers=headers)

html = req.text

html_doc = json.loads(html) #json.loads()解码python json格式

(三)提取信息

点击Preview,我们得到:

在这当中找到了我们想要的信息——交易所原始链接,文章id,时间,交易所名字,标题。有交易所的原始链接,MyToken的文章id不需要了。

提取方法如下:

print(html_doc)之后我们发现这是个字典,获得data数据,再获得list数据,如下

{'id': 30029, 'title': 'CEO交易所关于2019年4月7日CEO持仓、COO锁仓分红发放公告', 'abstract': 'https://ceo.bi/i/blog_c_1906.jsp', 'link': 'https://h5-cn-east.mytokenapi.com/native-support/announcement/?announceid=30029&language=zh_cn&legal_currency=cny&tt=1554652003', 'exchange_id': 1355, 'posted_at': 1554613703, 'lang_type': 'zh_cn', 'logo': 'https://cdn.mytoken.org/FhAuqDW1Xnqq61gOTkhNyVK2NcVv', 'exchange_name': 'CEO', 'exchange_alias': '', 'source': 'CEO'}

这样就变成我们可以直接获得的数据了,比如标题就用下面一行代码就能得到

title = html_doc.get('data').get(‘list')[n].get('title')

其它提取方法相同。

除此之外,这里的时间戳,需要将其转化为当地时间。

timestamp = html_doc.get('data').get('noticeInfoList')[n].get('ctime')

timeArray = time.localtime(timestamp)

now_time = time.strftime("%m-%d %H:%M", timeArray)

几项汇总到一起:

all = now_time +'\t' + source +'\t' + title +'\t' + abstract

(四)筛选我们想要的内容

我们可以把关注的关键字放到一个list中,比如与IEO相关的,注意中文要在前面加u进行转码,英文区分大小写。

key_array = [u"售卖",u"点卡","IEO",'Launchpad','Prime','Jumpstart’] 

通过判断上述关键字是否都在标题中,如果在就打印出来,再加上循环,并防止重复打印。

# 判断是否包含交易赛相关字眼,如果是,打印

for key in key_array:

   if key in title:

       print(page, all)

       break # 目的是当一个标题中出现多个关键词时,不用重复打印,只要打印一次就好了

最后网页默认是一页仅20条,我们想获得更多,加个页码的参数,并设定一个函数,循环获取每一页;过段时间网页的timestamp和code有可能还需要更新,也设为参数。

target ='https://speed-api.mytokenapi.com/media/medialist?type=6&keyword=exchange_announcement&need_pagination=1'  #此为Request URL

target = target +'&page='+str(page) +'&size=20'+'&timestamp='+ timestamp +'&code='+ code +'&platform=web_pc&v=1.0.0&language=zh_CN&legal_currency=CNY'

运行代码,查找与IEO相关的公告,一目了然。

如果漏掉一些公告,那说明关键字没设好,可以从公告标题中慢慢补全关键字。比如我把与交易赛相关的关键已经扩充到了这么多,争取一网打尽。

key_array = [u"瓜分", u"交易赛", u"强势", u"狂撒", u"排名", u"福利", u"奖励", u"糖果", u"赢", u"活动", u"PK赛", u"空投", u"壕送", u"大赛", u"礼", u"大奖", u"尽享", u"百万", u"送", u"倾情",  u"百万", u"送"]

你可以选择你关注的内容设置不同的关键字:

比如你非常关注EOS相关公告,你设置key_array = ['EOS']   

再比如你关注平台币相关公告,你设置key_array = ['BNB', 'HT', 'OKB'] 

再比如你关注上新相关信息,你设置key_array = [u"上新", u"上线"]  

关键字随便你调整,再也不用从茫茫大海中一个个筛选了。

(五)遇到问题

程序调试是一个非常耗费脑力和精力的事,出现问题最好先一个一个输出,根据错误代码找解决办法,这个程序代码并不多,但初学菜鸟的我弄了几乎一整天。

调试MyToken的时候发现只能打印四页左右的内容,怀疑是网站的时间戳与code(类似签名)问题,因为抓取是抓的别人写好的,那时间戳与签名只能用别人的,可更新之后时间戳就变了。找MyToken客服也解决不了,因为客服一般都是妹子,她说要上班了转给技术。

无奈去调试非小号公告集成网页https://www.feixiaohao.com/exchange/notice/,原理一样,只不过非小号无法调取交易所原始链接,只能用他自己的,那就需要调取文章的id,因为每一篇公告的链接其实就是https://t.bqi.com/news/id.html

id = html_doc.get('data').get('list')[n].get('art_id')

href ='https://t.bqi.com/news/%s.html' % id# 非小号电脑链接

all = create_time +'\t' + nick_name +'\t' + title +'\t' + href

而且最崩溃的是非小号上每一页requests的url都需要输入对应页码的timestamp,nonce,sign三个参数,获取20页得输入20次,也要累死个人,MyToken至少一个可以输出4页,我只好返回去解决MyToken的问题。

MyToken在获取第4页出现问题,一行一行输出,看下到底哪个参数出问题,发现是source这个交易所名称,又定位到是'id': 29969出现问题,查看原始数据,发现这条公告来源交易所为空None,这才导致相加时一直报错 {'id': 29969, 。。。'exchange_name': None, 'exchange_alias': '', 'source': None}。

于是加个条件判断,如果为空,去掉它,问题解决,输出50页也没问题了。

if source ==None:

           all = now_time +'\t' + title +'\t' + abstract

else:

all = now_time +'\t' + source +'\t' + title +'\t' + abstract

最后因为还在初学,难免出现差错,有问题欢迎交流。

附MyToken筛选公告总代码

import requests

import json

import time

import datetime

def get_contest_notice(page, key_array, timestamp, code):

    headers = {

'User - Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',

        'Referer':'https://www.mytoken.io/announcement/'

    }# 不同于交易所,此处不需要cookie

    target ='https://speed-api.mytokenapi.com/media/medialist?type=6&keyword=exchange_announcement&need_pagination=1'  #此为Request URL

    target = target +'&page=' +str(page) +'&size=20' +'&timestamp=' + timestamp +'&code=' + code +'&platform=web_pc&v=1.0.0&language=zh_CN&legal_currency=CNY'

    req = requests.get(url=target, headers=headers)

    html = req.text

    html_doc = json.loads(html)#json.loads()解码python json格式

    # print(html_doc)

    num =len(html_doc.get('data').get('list'))

    n =0

    while (n < num):

        source = html_doc.get('data').get('list')[n].get('source')

        title = html_doc.get('data').get('list')[n].get('title')

        timestamp = html_doc.get('data').get('list')[n].get('posted_at')

        timeArray = time.localtime(timestamp)

        now_time = time.strftime("%m-%d %H:%M", timeArray)

        abstract = html_doc.get('data').get('list')[n].get('abstract')# 交易所原始链接

        if source ==None:# 发现有一个数据来源是None,导致一直报错 

            all = now_time +'\t' + title +'\t' + abstract

        else:

            all = now_time +'\t' + source +'\t' + title +'\t' + abstract

        # 判断是否包含相关字眼,如果是,打印

        for key in key_array:

            if key in title:

                print(page, all)

                break  # 目的是当一个标题中出现多个关键词时,不用重复打印,只要打印一次就好了

        n = n +1

page =1

page_total =20  #最多页数

key_array = [u"售卖", u"点卡", "IEO", 'Launchpad', 'Prime', 'Jumpstart'] # 注意区分大小写

while page <= page_total:

    timestamp ='1554644184708'

    code ='ab0d7d408191dc0a411d0ed292588ff1'

    sum = get_contest_notice(page, key_array, timestamp, code)

    page = page +1

上一篇下一篇

猜你喜欢

热点阅读