其他 Ruby 抓疫情数据

xerox51 · 2020年03月06日 · 最后由 fleam 回复于 2022年03月25日 · 4388 次阅读

疫情让非程序员都宅不住了,在家自学 Ruby。使用 powershell 将打印的结果输出到 txt 时,中文会乱码,因此 encode 为 gbk。

# -*- coding: UTF-8 -*-
require "url"
require "json"

url = URL.new("https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback")
response = url.get.json
data0 = response["data"]

def json_to_hash(json)
  json_result = JSON.parse(json)
  return json_result
end

data = json_to_hash(data0)

def showworldinfectedinfo(data)
  tempdata = data["areaTree"]
  for item in tempdata
    puts (item["name"].to_s + "累计确诊:" + item["total"]["confirm"].to_s + "例,死亡:" + item["total"]["dead"].to_s + "例,治愈:" + item["total"]["heal"].to_s + "例;").encode("gbk")
  end
end

def updatetime(data)
  puts data["lastUpdateTime"]
end

updatetime(data)
showworldinfectedinfo(data)

帮你简化了一下,哈哈

require "url"
require "json"

url = URL.new("https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback")
response = url.get.json
data = JSON.parse response["data"]

puts data["lastUpdateTime"]

def show_data(data)
  for item in data["areaTree"]
    puts (item["name"].to_s + "累计确诊:" + item["total"]["confirm"].to_s + "例,死亡:" + item["total"]["dead"].to_s + "例,治愈:" + item["total"]["heal"].to_s + "例;").encode("gbk")
  end
end

show_data(data)

哈哈 可以。encode('utf-8') 应该比较通用些,难道是系统配置问题?我的机子是不需要 encode 都能输出正常数据的。

yangfeng05 回复

哈哈,Ruby 和 Python 真适合没有编程基础的初学者,写玩具代码首推这两个。这是 Python 查看中国疫情的代码。在家自学的。

import json
import requests

url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback'
res = requests.get(url).json()['data']
data = json.loads(res)

def showupdatetime(data):
    print(str(data['lastUpdateTime']))

def showchina(data):
    print ("中国累计确诊:" + str(data['chinaTotal']['confirm']) + "例,死亡:" + str(data['chinaTotal']['dead']) + "例,治愈:" + str(data['chinaTotal']['heal']) + "例。")
    print ("中国今日新增确诊:"  + str(data['chinaAdd']['confirm']) + "例,死亡:" + str(data['chinaAdd']['dead']) + "例,治愈:" + str(data['chinaAdd']['heal']) + "例。")

def showeverycity(data):
    list0 = data['areaTree']
    list1 = list0[0]
    list2 = list1['children']
    for province in list2:
        templist = province['children']
        print(province['name'] + "详情:")
        for item in templist:
            print(str(item['name']) + "今日新增确诊:" + str(item['today']['confirm']) + "例,累计确诊:" + str(item['total']['confirm']) + "例,死亡:"+str(item['total']['dead']) + "例,治愈:"+str(item['total']['heal'])+"例;")


showupdatetime(data)
showchina(data)
showeverycity(data)
lanzhiheng 回复

你尝试用 powershell, 假设这个 ruby 程序为 test.rb, 你在终端里输入 ruby test.rb >> output.txt, 你打开看下那个 txt 试试

5 楼 已删除

兼容 linux 和苹果系统:

require "url"
require "json"

url = URL.new("https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback")
response = url.get.json
data = JSON.parse response["data"]

puts data["lastUpdateTime"]

def show_data(data)
  for item in data["areaTree"]
    s=(item["name"].to_s + "累计确诊:" + item["total"]["confirm"].to_s + "例,死亡:" + item["total"]["dead"].to_s + "例,治愈:" + item["total"]["heal"].to_s + "例;")
    if Gem.win_platform?
      puts s.encode("gbk")
    else
      puts s
    end                                                                                  
  end
end

show_data(data)

乱码是因为 powershell out-file 的编码默认不是 Utf8。 如果想要避免 encode,可以把输出到文件做成参数。利用 Ruby 的 File 写入文件。 另外我稍微整理了一下代码。使用标准库来下载 json,通过一个辅助方法来同时支持输出到文件或 STDOUT。

# -*- coding: UTF-8 -*-
require "open-uri"
require "json"

def with_outs
  case ARGV[0]
  when String
    File.open(ARGV[0], 'w') { |f| yield f }
  else
    yield STDOUT
  end
end

with_outs do |outs|
  raw_body = URI.open('https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback').read
  response = JSON.parse(raw_body)
  data = JSON.parse(response['data'])
  outs.puts data['lastUpdateTime']
  data['areaTree'].each do |item|
    loc = item['name']
    count = item['total']
    line = "#{loc}累计确诊: #{count['confirm']}例, 死亡: #{count['dead']}例, 治愈: #{count['heal']}例;"
    outs.puts line
  end
end

在以下版本测试通过

$PSVersionTable -> 5.1.18362.628

ruby -v -> ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x64-mingw32]

执行方式:ruby tiny_server.rb 每次访问 localhost:94/whfy 时从腾讯新闻下载数据

之前玩着搞的,不更新

require 'json'
require 'open-uri'
require 'erb'

QQXW_INFO_PATH = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5'

#'http://view.inews.qq.com/g2/getOnsInfo?name=wuwei_ww_area_counts' # <- 这个和网页上显示的数据不相同

HEADER = {
  'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36'

}

def update_json_data
  puts '正在下载数据'
  qqxw_infos_handler = open(QQXW_INFO_PATH, HEADER)
  qqxw_infos_content = qqxw_infos_handler.read
  puts '下载数据完成, 正在解析..'
  domestic_datas = JSON.parse(JSON.parse(qqxw_infos_content)['data'])['areaTree'][0]['children']

  # 读取erb模板
  if !File.exist?('./page.erb')
    raise "找不到erb模板"
  end

  fio = File.open('./page.erb')
  fc = fio.read
  fio.close

  html_content = ERB.new(fc).result(binding)

  # 调试模块
  # require 'irb'
  # binding.irb

  # exit
  domestic_datas = nil # 释放内存
  fc = nil
  return html_content
end

# 加载sinatra
puts '加载sinatra'
require 'sinatra'


# 配置sinatra
configure do
  set :server, 'webrick'
  set :bind, '0.0.0.0'
  set :port, 94

end
# 设置跳转
get '/whfy' do
  return update_json_data()
end

<html>
<head><meta charset="utf-8"><title>武汉肺炎_腾讯新闻实时数据</title>
</head>
<body>
<!-- 记录中国省份总计 -->
<h2>省份汇总</h2>
<table border="1"><thead>
<tr>
<th>省份</th>
<th>共计确诊人数</th><th>共计疑似人数</th><th>共计死亡人数</th><th>共计治愈人数</th>
<th>本日新增确诊人数</th><th>本日新增疑似人数</th><th>本日新增死亡人数</th><th>本日新增治愈人数</th>
</tr>
</thead><tbody>
<!-- 腾讯新闻返回的省份数据已经按确诊人数排序好了的 -->
<% domestic_datas.each do |_current_area_info| %>

<%   total_count_confirm = _current_area_info['total']['confirm'] %>
<%   total_count_suspect = _current_area_info['total']['suspect'] %>
<%   total_count_dead = _current_area_info['total']['dead'] %>
<%   total_count_heal = _current_area_info['total']['heal'] %>
<%   today_count_confirm = _current_area_info['today']['confirm'] %>
<%   today_count_suspect = _current_area_info['today']['suspect'] %>
<%   today_count_dead = _current_area_info['today']['dead'] %>
<%   today_count_heal = _current_area_info['today']['heal'] %>

<tr>
<th><%= _current_area_info['name'] %></th>
<th><%= total_count_confirm  %></th>
<th><%= total_count_suspect  %></th>
<th><%= total_count_dead   %></th>
<th><%= total_count_heal  %></th>
<th><%= today_count_confirm  %></th>
<th><%= today_count_suspect  %></th>
<th><%= today_count_dead   %></th>
<th><%= today_count_heal  %></th>
</tr>
<% end %>

</tbody></table>

<br><br><br>
<!-- 记录中国各地区的详细信息 -->
<h2>中国地区详细信息</h2>
<table border="1"><thead>
<tr>
<th>大区名</th><th>地区名</th>
<th>共计确诊人数</th><th>共计疑似人数</th><th>共计死亡人数</th><th>共计治愈人数</th>
<th>本日新增确诊人数</th><th>本日新增疑似人数</th><th>本日新增死亡人数</th><th>本日新增治愈人数</th>
</tr>
</thead><tbody>
<% domestic_datas.each do |_current_area_info| %>
<%   current_cities_infos = _current_area_info['children'] %> 

<%   current_cities_infos.each do |_x| %>

    <tr>
    <th><%= _current_area_info['name'] %></th>
    <th><%= _x['name'] %></th>
    <th><%= _x['total']['confirm'] %></th>
    <th><%= _x['total']['suspect'] %></th>
    <th><%= _x['total']['dead'] %></th>
    <th><%= _x['total']['heal'] %></th>
    <th><%= _x['today']['confirm'] %></th>
    <th><%= _x['today']['suspect'] %></th>
    <th><%= _x['today']['dead'] %></th>
    <th><%= _x['today']['heal'] %></th>
    </tr>

<% end %>
<% end %>

</tbody></table>


</body>
</html>
yangfeng05 回复

你要是这么玩的话,确实好玩。。。

require 'net/http'
require "json"

for item in (JSON.parse (JSON.parse Net::HTTP.get_response(URI('https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback')).body)["data"])["areaTree"]
    puts (item["name"].to_s + "累计确诊:" + item["total"]["confirm"].to_s + "例,死亡:" + item["total"]["dead"].to_s + "例,治愈:" + item["total"]["heal"].to_s + "例;").encode("gbk")
end

需要 登录 后方可回复, 如果你还没有账号请 注册新账号