C# 爬虫:疫情实时信息图

一图胜千言,利用图表控件进行数据展示已成为一种趋势,所以为推荐本篇文章给大家,希望能够有所帮助。

示例截图,运行结果:.

C# 爬虫:疫情实时信息图

疫情实时地图源码

疫情实时地图源码如下所示:

using System;using System.Drawing;using System.Text;using NSoup;using NSoup.Nodes;using System.IO;using System.Net;using System.Text.RegularExpressions;using System.Windows.Forms;namespace Pneumonia{    public partial class MainForm : DevComponents.DotNetBar.OfficeForm    {        static string confirmedCount, suspectedCount, deadCount, curedCount, updateTime, dataUpdateTime;        static string url = "https://3g.dxy.cn/newh5/view/pneumonia";        static int count = 0;        static Document doc;        public MainForm(){            this.EnableGlass = false;            InitializeComponent();            this.SizeChanged += new Resize(this).Form1_Resize;  //窗口自适应代码        }        private void MainForm_Load(object sender, EventArgs e){            timer1.Enabled = true;            timer1.Interval = 1;            timer1.Start();            WebClient wc = new WebClient();            byte[] htmlData = wc.DownloadData(url);            string html = Encoding.UTF8.GetString(htmlData);            logWrite(html);//将网页内容写入txt文件,以方便查看            toolStripStatusLabel1.Text = DateTime.Now.ToString();        }        private void timer1_Tick(object sender, EventArgs e){            dataUpdateTime = DateTime.Now.ToString();            count++;            timer1.Interval = 300000;            GetData();            lbl1.Text = "☛ 病毒: " + regularMatchStr("getStatisticsService", "virus\":\"(.+?)\",");            lbl2.Text = "☛ 传染源: " + regularMatchStr("getStatisticsService", "infectSource\":\"(.+?)\",");            lbl3.Text = "☛ 传播途径: " + regularMatchStr("getStatisticsService", "passWay\":\"(.+?)\",");            lbl4.Text = "☛ " + regularMatchStr("getStatisticsService", "remark1\":\"(.+?)\",");            lbl5.Text = "☛ " + regularMatchStr("getStatisticsService", "remark2\":\"(.+?)\",");            Image map = UrlToImage("https://img1.dxycdn.com/2020/0201/450/3394153392393266839-135.png");            pictureBox1.Image = map;            Image chart = UrlToImage("https://img1.dxycdn.com/2020/0201/693/3394145745204021706-135.png");            pictureBox2.Image = chart;            updateTimeLbl.Text = "截至 " + updateTime + " 全国数据统计";            confirmedLbl.Text = confirmedCount;            suspectedLbl.Text = suspectedCount;            deadLbl.Text = deadCount;            curedLbl.Text = curedCount;        }        public static void GetData(){            //直接通过url来获取Document对象            doc = NSoupClient.Connect(url).Get();            //先获取id为artContent的元素,再获取所有的p标签            updateTime = ConvertStringToDateTime(regularMatchStr("getStatisticsService", "modifyTime\":(.+?),")).ToString();            confirmedCount = regularMatchStr("getStatisticsService", "confirmedCount\":(.+?),");            suspectedCount = regularMatchStr("getStatisticsService", "suspectedCount\":(.+?),");            deadCount = regularMatchStr("getStatisticsService", "deadCount\":(.+?),");            curedCount = regularMatchStr("getStatisticsService", "curedCount\":(.+?),");        }        #region 下载图片到Image        public static Image UrlToImage(string url){            WebClient mywebclient = new WebClient();            byte[] Bytes = mywebclient.DownloadData(url);            using (MemoryStream ms = new MemoryStream(Bytes))            {                Image outputImg = Image.FromStream(ms);                return outputImg;            }        }        #endregion        public static DateTime ConvertStringToDateTime(string timeStamp){            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));            long lTime = long.Parse(timeStamp + "0000");            TimeSpan toNow = new TimeSpan(lTime);            return dtStart.Add(toNow);        }        public static string regularMatchStr(string elementId, string regex){            Element p = doc.GetElementById(elementId);            Regex reg = new Regex(regex, RegexOptions.IgnoreCase);            //例如我想提取line中的NAME值            Match match = reg.Match(p.Html());            string value = match.Groups[1].Value;            return value;        }        public static void logWrite(string Message){            if (!File.Exists(AppDomain.CurrentDomain.BaseDirectory + "\\log.txt"))                File.Create(AppDomain.CurrentDomain.BaseDirectory + "\\log.txt").Close();            string fileName = AppDomain.CurrentDomain.BaseDirectory + "\\log.txt";            string content = DateTime.Now.ToLocalTime() + Message + "\r\n";            StreamWriter sw = new StreamWriter(fileName, true);            sw.Write(content);            sw.Close(); sw.Dispose();        }        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e){            if (e.Button == MouseButtons.Left)//判断鼠标的按键                        {                //点击时判断form是否显示,显示就隐藏,隐藏就显示                               if (this.WindowState == FormWindowState.Normal)                {                    this.WindowState = FormWindowState.Minimized;                    this.Hide();                }                else if (this.WindowState == FormWindowState.Minimized)                {                    this.Show();                    this.WindowState = FormWindowState.Normal;                    this.Activate();                }            }            else if (e.Button == MouseButtons.Right)            {                //右键退出事件                                if (MessageBox.Show("是否需要关闭程序?", "提示:", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.OK)//出错提示                                {                    //关闭窗口                                        DialogResult = DialogResult.No;                    Dispose();                    Close();                }            }        }        private void timer2_Tick(object sender, EventArgs e){            toolStripStatusLabel1.Text = DateTime.Now.ToString() + "  刷新次数 : " + count + "  最新刷新时间 :" + dataUpdateTime;        }        private void MainForm_FormClosing(object sender, FormClosingEventArgs e){            if (MessageBox.Show("是否确认退出程序?", "退出", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)            {                // 关闭所有的线程                this.Dispose();                this.Close();            }            else            {                e.Cancel = true;            }        }        private void MainForm_SizeChanged(object sender, EventArgs e){            //判断是否选择的是最小化按钮            if (WindowState == FormWindowState.Minimized)            {                //隐藏任务栏区图标                this.ShowInTaskbar = false;                //图标显示在托盘区                notifyIcon1.Visible = true;            }        }        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)        {            if (MessageBox.Show("是否确认退出程序?", "退出", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)            {                // 关闭所有的线程                this.Dispose();                this.Close();            }        }        private void 显示ToolStripMenuItem_Click(object sender, EventArgs e)        {            WindowState = FormWindowState.Normal;        }    }}

resize类

using System;using System.Collections.Generic;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace Pneumonia{    class Resize    {        private MainForm _form;        public Resize(MainForm form)        {            int count = form.Controls.Count * 2 + 2;            float[] factor = new float[count];            int i = 0;            factor[i++] = form.Size.Width;            factor[i++] = form.Size.Height;            foreach (Control ctrl in form.Controls)            {                factor[i++] = ctrl.Location.X / (float)form.Size.Width;                factor[i++] = ctrl.Location.Y / (float)form.Size.Height;                ctrl.Tag = ctrl.Size;            }            form.Tag = factor;            this._form = form;        }        public void Form1_Resize(object sender, EventArgs e)        {            float[] scale = (float[])this._form.Tag;            int i = 2;            foreach (Control ctrl in this._form.Controls) //panel的长宽增长到一个固定的值就不会再增长了,原因:Panel的宽和高上限是65535像素(https://blog.csdn.net/dufangfeilong/article/details/41805073?utm_source=blogxgwz5)            {                ctrl.Left = (int)(this._form.Size.Width * scale[i++]);                ctrl.Top = (int)(this._form.Size.Height * scale[i++]);                ctrl.Width = (int)(this._form.Size.Width / (float)scale[0] * ((Size)ctrl.Tag).Width);                ctrl.Height = (int)(this._form.Size.Height / (float)scale[1] * ((Size)ctrl.Tag).Height);            }        }    }}

C# Winform控件自适应窗体大小:方法1(推荐)

需求:当窗体尺寸动态改变时,窗体中的各种控件(包括Panel以及Panel中的子控件)可以动态调节自身大小,以适应窗体内容比例。

方法:

第一步,新建一个类,代码如下:

public class Resize{  private Form _form;  public Resize(Form form)  {    int count = form.Controls.Count * 2 + 2;    float[] factor = new float[count];    int i = 0;    factor[i++] = form.Size.Width;    factor[i++] = form.Size.Height;    foreach (Control ctrl in form.Controls)    {      factor[i++] = ctrl.Location.X / (float)form.Size.Width;      factor[i++] = ctrl.Location.Y / (float)form.Size.Height;      ctrl.Tag = ctrl.Size;    }    form.Tag = factor;    this._form = form;  }  public void Form1_Resize(object sender, EventArgs e)  {    float[] scale = (float[])this._form.Tag;    int i = 2;    foreach (Control ctrl in this._form.Controls) //panel的长宽增长到一个固定的值就不会再增长了,原因:Panel的宽和高上限是65535像素(https://blog.csdn.net/dufangfeilong/article/details/41805073?utm_source=blogxgwz5)    {      ctrl.Left = (int)(this._form.Size.Width * scale[i++]);      ctrl.Top = (int)(this._form.Size.Height * scale[i++]);      ctrl.Width = (int)(this._form.Size.Width / (float)scale[0] * ((Size)ctrl.Tag).Width);      ctrl.Height = (int)(this._form.Size.Height / (float)scale[1] * ((Size)ctrl.Tag).Height);    }  }}

第二步,在Form的初始化函数中使用这个类:

public Form_StockCount(){  InitializeComponent();
  this.SizeChanged += new Resize(this).Form1_Resize;  //窗口自适应代码}

C# Winform窗体和控件自适应大小:方法2

1,在项目中创建类AutoSizeForm

AutoSizeForm.cs文件代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace CSharpFormApplication{    class AutoResizeForm    {            //(1).声明结构,只记录窗体和其控件的初始位置和大小。            public struct controlRect            {                public int Left;                public int Top;                public int Width;                public int Height;            }            //(2).声明 1个对象            //注意这里不能使用控件列表记录 List nCtrl;,因为控件的关联性,记录的始终是当前的大小。            //      public List oldCtrl= new List();//这里将西文的大于小于号都过滤掉了,只能改为中文的,使用中要改回西文            public List<controlRect> oldCtrl = new List<controlRect>();            int ctrlNo = 0;//1;            //(3). 创建两个函数            //(3.1)记录窗体和其控件的初始位置和大小,            public void controllInitializeSize(Control mForm)            {                controlRect cR;                cR.Left = mForm.Left; cR.Top = mForm.Top; cR.Width = mForm.Width; cR.Height = mForm.Height;                oldCtrl.Add(cR);//第一个为"窗体本身",只加入一次即可                AddControl(mForm);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用                //this.WindowState = (System.Windows.Forms.FormWindowState)(2);//记录完控件的初始位置和大小后,再最大化                //0 - Normalize , 1 - Minimize,2- Maximize            }            private void AddControl(Control ctl)            {                foreach (Control c in ctl.Controls)                {  //**放在这里,是先记录控件的子控件,后记录控件本身                    //if (c.Controls.Count > 0)                    //    AddControl(c);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用                    controlRect objCtrl;                    objCtrl.Left = c.Left; objCtrl.Top = c.Top; objCtrl.Width = c.Width; objCtrl.Height = c.Height;                    oldCtrl.Add(objCtrl);                    //**放在这里,是先记录控件本身,后记录控件的子控件                    if (c.Controls.Count > 0)                        AddControl(c);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用                }            }            //(3.2)控件自适应大小,            public void controlAutoSize(Control mForm)            {                if (ctrlNo == 0)                { //*如果在窗体的Form1_Load中,记录控件原始的大小和位置,正常没有问题,但要加入皮肤就会出现问题,因为有些控件如dataGridView的的子控件还没有完成,个数少                    //*要在窗体的Form1_SizeChanged中,第一次改变大小时,记录控件原始的大小和位置,这里所有控件的子控件都已经形成                    controlRect cR;                    //  cR.Left = mForm.Left; cR.Top = mForm.Top; cR.Width = mForm.Width; cR.Height = mForm.Height;                    cR.Left = 0; cR.Top = 0; cR.Width = mForm.PreferredSize.Width; cR.Height = mForm.PreferredSize.Height;
                    oldCtrl.Add(cR);//第一个为"窗体本身",只加入一次即可                    AddControl(mForm);//窗体内其余控件可能嵌套其它控件(比如panel),故单独抽出以便递归调用                }                float wScale = (float)mForm.Width / (float)oldCtrl[0].Width;//新旧窗体之间的比例,与最早的旧窗体                float hScale = (float)mForm.Height / (float)oldCtrl[0].Height;//.Height;                ctrlNo = 1;//进入=1,第0个为窗体本身,窗体内的控件,从序号1开始                AutoScaleControl(mForm, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用            }            private void AutoScaleControl(Control ctl, float wScale, float hScale)            {                int ctrLeft0, ctrTop0, ctrWidth0, ctrHeight0;                //int ctrlNo = 1;//第1个是窗体自身的 Left,Top,Width,Height,所以窗体控件从ctrlNo=1开始                foreach (Control c in ctl.Controls)                { //**放在这里,是先缩放控件的子控件,后缩放控件本身                    //if (c.Controls.Count > 0)                    //   AutoScaleControl(c, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用                    ctrLeft0 = oldCtrl[ctrlNo].Left;                    ctrTop0 = oldCtrl[ctrlNo].Top;                    ctrWidth0 = oldCtrl[ctrlNo].Width;                    ctrHeight0 = oldCtrl[ctrlNo].Height;                    //c.Left = (int)((ctrLeft0 - wLeft0) * wScale) + wLeft1;//新旧控件之间的线性比例                    //c.Top = (int)((ctrTop0 - wTop0) * h) + wTop1;                    c.Left = (int)((ctrLeft0) * wScale);//新旧控件之间的线性比例。控件位置只相对于窗体,所以不能加 + wLeft1                    c.Top = (int)((ctrTop0) * hScale);//                    c.Width = (int)(ctrWidth0 * wScale);//只与最初的大小相关,所以不能与现在的宽度相乘 (int)(c.Width * w);                    c.Height = (int)(ctrHeight0 * hScale);//                    ctrlNo++;//累加序号                    //**放在这里,是先缩放控件本身,后缩放控件的子控件                    if (c.Controls.Count > 0)                        AutoScaleControl(c, wScale, hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用
                    if (ctl is DataGridView)                    {                        DataGridView dgv = ctl as DataGridView;                        Cursor.Current = Cursors.WaitCursor;
                        int widths = 0;                        for (int i = 0; i < dgv.Columns.Count; i++)                        {                            dgv.AutoResizeColumn(i, DataGridViewAutoSizeColumnMode.AllCells);  // 自动调整列宽                              widths += dgv.Columns[i].Width;   // 计算调整列后单元列的宽度和                                               }                        if (widths >= ctl.Size.Width)  // 如果调整列的宽度大于设定列宽                              dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;  // 调整列的模式 自动                          else                            dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;  // 如果小于 则填充  
                        Cursor.Current = Cursors.Default;                    }                }            }        }    }

2,在要自适应大小的Form中自定义全局类对象
AutoResizeForm asc = new AutoResizeForm();
3,在要自适应大小的Form的load事件和SizeChange事件中执行对象方法

private void WidgetAutoResizeForm_Load(object sender, EventArgs e){  asc.controllInitializeSize(this);}
private void WidgetAutoResizeForm_SizeChanged(object sender, EventArgs e){  asc.controlAutoSize(this);}

From窗体代码:WidgetAutoResizeForm源码如下所示:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;
namespace CSharpFormApplication{    public partial class WidgetAutoResizeForm : Form    {        AutoResizeForm asc = new AutoResizeForm();        public WidgetAutoResizeForm()        {            InitializeComponent();        }
        private void WidgetAutoResizeForm_Load(object sender, EventArgs e)        {            asc.controllInitializeSize(this);        }
        private void WidgetAutoResizeForm_SizeChanged(object sender, EventArgs e)        {            asc.controlAutoSize(this);        }    }}