|
【得捷电子Follow me第1期】+ 在线新闻浏览器
连接WIFI
获取新闻
在OLED屏幕上显示新闻
import time
import network
import urequests
import urequests as requests
import ujson
from machine import Pin, I2C, ADC, PWM
from time import sleep
import ufont
import ssd1306
ssid = 'ccqp'
password = ''
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
# Wait for connect or fail
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('waiting for connection...')
time.sleep(1)
# Handle connection error
if wlan.status() != 3:
raise RuntimeError('network connection failed')
else:
print('connected')
status = wlan.ifconfig()
print( 'ip = ' + status[0] )
import ntptime
def sync_ntp():
ntptime.NTP_DELTA = 3155644800#3155673600#3155644800 # 可选 UTC+8偏移时间(秒),不设置就是UTC0
ntptime.host = 'ntp1.aliyun.com' # 可选,ntp服务器,默认是"pool.ntp.org"
ntptime.settime() # 修改设备时间,到这就已经设置好了
sync_ntp()
# 已经设置好了,随便用
from machine import RTC
rtc = RTC()
print(rtc.datetime())
#可以通过字典对象上值的键来获取每个单独的JSON值
##可借助ujson库来解析内容
import urequests
Url = 'https://api.seniverse.com/v3/weather/now.json?key=SK6E_7MBhPJr0_Cs3&location=shenzhen&language=zh-Hans&unit=c'
r = urequests.get(Url)
r.json()
print (r.json()['results'][0]['location']['name'],r.json()['results'][0]['now']['temperature'],r.json()['results'][0]['now']['text'])
i2c = I2C(1, scl=Pin(7), sda=Pin(6), freq = 400000)
display = ssd1306.SSD1306_I2C(128, 64, i2c)
# 载入字体
# 使用字体制作工具:javascript:;
font = ufont.BMFont("unifont-14-12917-16.v3.bmf")
request_url = 'javascript:;'
resp = urequests.get(request_url)
#resp_json = ujson.loads(resp.text)
print (resp.json()['result']['data'][0]['title'])
print (resp.json()['result']['data'][1]['title'])
print (resp.json()['result']['data'][2]['title'])
print (resp.json()['result']['data'][3]['title'])
titile=resp.json()['result']['data'][1]['uniquekey']
print (titile)
request_url1 = 'https://v.juhe.cn/toutiao/content?key=5f78766a1e82f665528a474b411a59dc&uniquekey='+ titile
#resp1 = urequests.get(request_url1)
#print (resp1.json()['result']['content'])
font.text(display, resp.json()['result']['data'][0]['title'], 0, 0, font_size=16, show=True, clear=True)
font.text(display, resp.json()['result']['data'][1]['title'], 0, 16, font_size=16, show=True, clear=True)
font.text(display, resp.json()['result']['data'][2]['title'], 0, 32, font_size=16, show=True, clear=True)
font.text(display, resp.json()['result']['data'][3]['title'], 0, 48, font_size=16, show=True, clear=True)
第一部分,就不再赘述。
第二部分,也是最有难度的部分是获取新闻,如何连上新闻服务器,获取并返回我们要的新闻?
本文重点讲解此部分代码。
我们打开他的官网,找到API,再找到新闻头条。
可以看到普通会员(免费注册的)每天可以查询50次。
接下来我们看下接口文档及示例代码。
可以看到新闻列表的接口地址是javascript:;
新闻正文的接口地址是 http://v.juhe.cn/toutiao/content
主要的代码就是Python下的Request语句。这条语句的主要参数有三个参数,url、type和key。
第一个参数url也就是网址,上文提到了新闻列表和新闻正文各自对应的url。
第二个参数是type,也就是你要获取的新闻的类型:
top(推荐,默认)
guonei(国内)
guoji(国际)
yule(娱乐)
tiyu(体育)
junshi(军事)
keji(科技)
caijing(财经)
youxi(游戏)
qiche(汽车)
jiankang(健康)
第三个参数,就是在聚合数据免费注册的普通会员,每个应用对于的密钥。
比如,这是我免费申请的Key。
以上3个参数弄明白后,就可以着手准备咱们的micropython代码了。
在这里主要参考了一段天气预报的代码,如下:
import urequests
Url = 'https://api.seniverse.com/v3/weather/now.json?key=SK6E_7MBhPJr0_Cs3&location=shenzhen&language=zh-Hans&unit=c'
上面这句至关重要,可以看到几个重要参数,第一个就是网址url,第二个就是key也就是密码,第三个就是位置,这里设置为深圳。
r = urequests.get(Url)
urequests.get这句就是核心语句,从指定网址的指定接口抓取信息,抓到的信息存在对象r中。
r.json()
将数据以json的格式整理。
json的全称为:JavaScript Object Notation,是一种轻量级的数据交互格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
简单来说:json就是一种在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互。
我们如果直接把带参数的url输入到浏览器,就会返回一长串看似杂乱的字符串,其实这就是Json格式的信息。
为了便于读懂这段Json格式的信息,我们可以使用“聚合数据”自带的JSON在线格式化工具,方便整理读懂信息。
https://tool.juhe.cn/
按上图的逻辑关系:
['results'][0]['location']['name']就对应“深圳”
['results'][0]['now']['temperature']就对应“29”
['results'][0]['now']['text']就对应“阴”
所以最后把你想要的信息打印出来。
print (r.json()['results'][0]['location']['name'],r.json()['results'][0]['now']['temperature'],r.json()['results'][0]['now']['text'])
运行结果如图红框内。
理解了天气预报的逻辑,获取新闻就简单了。
request_url = 'javascript:;'
resp = urequests.get(request_url)
print (resp.json()['result']['data'][0]['title'])
print (resp.json()['result']['data'][1]['title'])
print (resp.json()['result']['data'][2]['title'])
print (resp.json()['result']['data'][3]['title'])
我们将带参数的网址粘贴到浏览器。
因此,
['result']['data'][0]['title'] 就对应“小型飞机闯入禁区被法战机拦截:嫌犯高空抛下15个袋子 疑为毒品”
['result']['data'][1]['title'] 就对应“反复“退群”“返群”,美国把加入国际组织当作逛公园”
上面只是这条新闻的标题,那如果想要获取新闻的正文怎么办呢?
回到前面的介绍。
新闻正文的接口地址是 http://v.juhe.cn/toutiao/content
这里有两个关键参数,第一个仍然是密码,前文有说。
第二个参数就是uniquekey,这其实对应的是刚刚第一步获取新闻标题里JSON数据里的uniquekey。
我们直接把获取新闻正文的网址输入浏览器:
titile=resp.json()['result']['data'][1]['uniquekey']
此句获取新闻的'uniquekey'
print (titile)
打印出'uniquekey'
request_url1 = 'https://v.juhe.cn/toutiao/content?key=5f78766a1e82f665528a474b411a59dc&uniquekey='+ titile
抓取新闻正文的链接
resp1 = urequests.get(request_url1)
抓取新闻正文
print (resp1.json()['result']['content'])
第三部分 中文显示
需要把上图3个文件下载到PICO W板卡上。
i2c = I2C(1, scl=Pin(7), sda=Pin(6), freq = 400000)
display = ssd1306.SSD1306_I2C(128, 64, i2c)
# 载入字体
# 使用字体制作工具:javascript:;
font = ufont.BMFont("unifont-14-12917-16.v3.bmf")
font.text(display, resp.json()['result']['data'][0]['title'], 0, 0, font_size=16, show=True, clear=True)
font.text(display, resp.json()['result']['data'][1]['title'], 0, 16, font_size=16, show=True, clear=True)
font.text(display, resp.json()['result']['data'][2]['title'], 0, 32, font_size=16, show=True, clear=True)
font.text(display, resp.json()['result']['data'][3]['title'], 0, 48, font_size=16, show=True, clear=True)
执行结果如下图
MMMMMM
2. 功能展示及说明
功能展示如图所示,列出了4条国际新闻标题,由于MicroPython-uFont 默认超出边界不换行,因此标题未显示完全。
另外,由于此屏幕比较小,128*64,只能显示4行中文,而且没有按钮等翻屏工具,因此目前没有再深入编写进一步的功能,也算给后续开发留点悬念吧。
其他的展示:
任务1:熟悉micropython基本语法
这里要特别指出,单击要上传的文件,右键有“上传到/”就可以很便捷地实现程序上传功能。
另外,为了便于学习python语言,推荐以下网址:
任务2:驱动外设
任务3:同步网络时间
任务4:实现定位功能
由于在室内,GPS信号不支持,放到室外就好很多。
本次活动是我第一次开发树莓派,也是第一次体验Micro-Python,以往的开发经历比如51单片机及MSP430单片机,都需要特别关注处理器的底层细节,比如时钟、寄存器,还需要专门的烧录工具,而且由于51单片机及MSP430单片机的资源比较有限,时钟频率也不高,可玩性就不那么丰富,这次Digi-Key联合EEWORLD发起的"Follow me活动”,给了我一个完整的开发体验,Digi-Key上有丰富的外设资源,完全能满足我的开发需求。
最后附上全部代码,包括原创的《卡农》。