1. 程式人生 > >爬蟲雙色球所有的歷史資料並儲存到SQLite

爬蟲雙色球所有的歷史資料並儲存到SQLite

前言

上一篇介紹了雙色球走勢圖是怎麼實現的,這一篇介紹怎麼實現爬蟲所有的雙色球歷史資料,也可以同步分享怎麼同步福彩3D資料。採用的C#來實現的。

同步雙色球的地址:https://datachart.500.com/ssq/history/newinc/history.php?start={0}&end={1} 

同步福彩3D的地址:https://datachart.500.com/sd/history/inc/history.php?start={0}&end={1}

上一篇介紹走勢圖的實現:https://www.cnblogs.com/luoyuhao/p/13887935.html

開啟網站顯示的資料如下:

 

 

 

 

 

實現爬蟲的過程

建立接收儲存雙色球歷史資料的table

 

 抓取網站上的html ,再通過html 去解析相應的資料。

 

 

通過以上擷取後就只剩下需要的雙色球的歷史資料了,再去擷取tr td資料,就相應能到得到相應的資料了,是不是很簡單的一件事呀!

 

解析tr所有資料

 

 

        /// <summary>
        /// 雙色球TR
        /// </summary>
        /// <param name="wnRepo"></param>
        /// <param name="content"><tbody></tbody>之間的內容</param>
        private void ResolveSSQTr(string content)
        {
            string trContent = string.Empty;
            Regex regex = new Regex("<tr class=\"t_tr1\">");
            //在<tbody></tbody>之間的內容搜尋所有匹配<tr>的項
            MatchCollection matches = regex.Matches(content);
            foreach (Match item in matches)
            {
                //如果當前匹配項的下一個匹配項的值不為空
                if (!string.IsNullOrEmpty(item.NextMatch().Value))
                {
                    trContent = content.Substring(item.Index, item.NextMatch().Index - item.Index);
                }
                //最後一個<tr>的匹配項
                else
                {
                    trContent = content.Substring(item.Index, content.Length - item.Index);
                }
                DataRow dr = ssqdt.NewRow();
                ResolveSSQTd(ref dr, trContent);

                ssqdt.Rows.Add(dr);
            }
}

 

解析所有td內容

 /// <summary>
        /// 雙色球TD
        /// </summary>
        /// <param name="dr"></param>
        /// <param name="trContent"></param>
        private void ResolveSSQTd(ref DataRow dr, string trContent)
        {
            List<int> redBoxList = null;
            //匹配期號的表示式
            string patternQiHao = "<td>";
            Regex regex = new Regex(patternQiHao);
            Match qhMatch = regex.Match(trContent);
            dr["QiHao"] = trContent.Substring(qhMatch.Index + 13 + patternQiHao.Length, 5);

            if (int.Parse(trContent.Substring(qhMatch.Index + 13 + patternQiHao.Length, 5)) % 2 == 0)
            {
                dr["Type"] = "雙期";
            }
            else
            {
                dr["Type"] = "單期";
            }

            //存放匹配出來的紅球號碼
            redBoxList = new List<int>();
            //匹配紅球的表示式
            string patternChartBall = "<td class=\"t_cfont2\">";
            regex = new Regex(patternChartBall);
            MatchCollection rMatches = regex.Matches(trContent);
            foreach (Match r in rMatches)
            {
                redBoxList.Add(Convert.ToInt32(trContent.Substring(r.Index + patternChartBall.Length, 2)));
            }

            //匹配紅球的表示式
            patternChartBall = "<td class=\"t_cfont4\">";
            regex = new Regex(patternChartBall);
            rMatches = regex.Matches(trContent);

            foreach (Match r in rMatches)
            {
                dr["B"] = Convert.ToInt32(trContent.Substring(r.Index + patternChartBall.Length, 2));
                break;
            }

            patternChartBall = @"\d{4}-\d{2}-\d{2}";
            regex = new Regex(patternChartBall);
            rMatches = regex.Matches(trContent);
            foreach (Match r in rMatches)
            {
                DateTime dt = Convert.ToDateTime(r.Value);
                dr["OpenDate"] = dt;
                dr["Week"] = CaculateWeekDay(dt.Year, dt.Month, dt.Day);
            }

            //排序紅球號碼
            redBoxList.Sort();
            //紅球號碼
            dr["R1"] = redBoxList[0];
            dr["R2"] = redBoxList[1];
            dr["R3"] = redBoxList[2];
            dr["R4"] = redBoxList[3];
            dr["R5"] = redBoxList[4];
            dr["R6"] = redBoxList[5];
            dr["HTML"] = trContent;
        }

儲存所解析的資料儲存到SQLite

if (!Directory.Exists(tempPath))//判斷資料夾是否存在
                Directory.CreateDirectory(tempPath);//建立資料夾在根目錄下
            string _db = System.IO.Path.Combine(tempPath, "cpdb.dll");
            SQLiteHelper helper = new SQLiteHelper(_db);
            OperResult oper = new OperResult();

            helper.ExecuteNonQuery(string.Format("drop table if exists {0}", ssqtableName), _db);

            string msg = string.Format("create table if not exists {0} (\r\n", ssqtableName);
            for (int i = 0; i < ssqdt.Columns.Count; i++)
            {
                msg += string.Format("{0} {1},\r\n", ssqdt.Columns[i].ColumnName, helper.TypeToSqliteType(ssqdt.Columns[i].DataType));
            }
            msg = msg.Remove(msg.LastIndexOf(",\r\n"), 3);
            msg += ")";

            oper = helper.ExecuteNonQuery(msg, _db);
            oper = helper.SaveDataTable(ssqdt, ssqtableName);

獲取網頁內容的方法

      public static string HttpGet(string url,string encoding)
        {
            WebRequest request = HttpWebRequest.Create(url);
            WebResponse response = request.GetResponse();
           
            Stream stream = response.GetResponseStream();
            StreamReader reader = new StreamReader(stream, Encoding.GetEncoding(encoding));
            string content = reader.ReadToEnd();
            return content;
        }

基姆拉爾森計算公式計算日期

/// <summary>      
        /// 基姆拉爾森計算公式計算日期
        /// </summary> 
        /// <param name="y">年</param> 
        /// <param name="m">月</param> 
        /// <param name="d">日</param> 
        /// <returns>星期幾</returns> 
        protected string CaculateWeekDay(int y, int m, int d)
        {
            if (m == 1 || m == 2)
            {
                m += 12;
                y--;
                //把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10則換算成:2003-13-10來代入公式計算。
            }
            int week = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;
            string weekstr = "";
            switch (week)
            {
                case 0: weekstr = "週一"; break;
                case 1: weekstr = "週二"; break;
                case 2: weekstr = "週三"; break;
                case 3: weekstr = "週四"; break;
                case 4: weekstr = "週五"; break;
                case 5: weekstr = "週六"; break;
                case 6: weekstr = "週日"; break;
            }
            return weekstr;
        }

儲存完後,顯示的形式就是以DLL結尾的檔案了,如下圖:

 

 怎麼讀取儲存的雙色球資料

   string _db = System.IO.Path.Combine(tempPath, "cpdb.dll");
            SQLiteHelper helper = new SQLiteHelper(_db);
            OperResult oper = new OperResult();
            oper = helper.GetDataSet(string.Format("select * from {0}", ssqtableName), _db);
            if (oper.State == 1 && oper.DataSet != null && oper.DataSet.Tables.Count > 0 && oper.DataSet.Tables[0].Rows.Count > 0)
            {
                ViewBag.QiHao = "第" + oper.DataSet.Tables[0].Rows[0]["QiHao"] + "期";
                ViewBag.B = oper.DataSet.Tables[0].Rows[0]["B"].ToString().Length == 1 ? "0" + oper.DataSet.Tables[0].Rows[0]["B"].ToString() : oper.DataSet.Tables[0].Rows[0]["B"].ToString();
                ViewBag.R1 = oper.DataSet.Tables[0].Rows[0]["R1"].ToString().Length == 1 ? "0" + oper.DataSet.Tables[0].Rows[0]["R1"].ToString() : oper.DataSet.Tables[0].Rows[0]["R1"].ToString();
                ViewBag.R2 = oper.DataSet.Tables[0].Rows[0]["R2"].ToString().Length == 1 ? "0" + oper.DataSet.Tables[0].Rows[0]["R2"].ToString() : oper.DataSet.Tables[0].Rows[0]["R2"].ToString();
                ViewBag.R3 = oper.DataSet.Tables[0].Rows[0]["R3"].ToString().Length == 1 ? "0" + oper.DataSet.Tables[0].Rows[0]["R3"].ToString() : oper.DataSet.Tables[0].Rows[0]["R3"].ToString();
                ViewBag.R4 = oper.DataSet.Tables[0].Rows[0]["R4"].ToString().Length == 1 ? "0" + oper.DataSet.Tables[0].Rows[0]["R4"].ToString() : oper.DataSet.Tables[0].Rows[0]["R4"].ToString();
                ViewBag.R5 = oper.DataSet.Tables[0].Rows[0]["R5"].ToString().Length == 1 ? "0" + oper.DataSet.Tables[0].Rows[0]["R5"].ToString() : oper.DataSet.Tables[0].Rows[0]["R5"].ToString();
                ViewBag.R6 = oper.DataSet.Tables[0].Rows[0]["R6"].ToString().Length == 1 ? "0" + oper.DataSet.Tables[0].Rows[0]["R6"].ToString() : oper.DataSet.Tables[0].Rows[0]["R6"].ToString();
            }

以上即完成雙色球歷史資料的爬蟲和儲存資料的全部過程,思路非常清晰,而且方法容易,這樣就不需要呼叫收費的介面了,為開發雙色球走勢圖打好良好的基礎 ,大家有沒有覺得非常容易呀!其實爬蟲的方法很多,希望跟大家一起交流學習了,也可以通過正則表達是來獲取相應的資料,也可以用第三方工具去解析更簡單快捷,曾經我也做過相應的爬蟲,還挺好玩的。

爬蟲福彩3D資料

 

 同樣顯示建立接收資料的表結構來接收資料。

 

 解析tr資料

string trContent = string.Empty;
            Regex regex = new Regex("<tr>");
            //在<tbody></tbody>之間的內容搜尋所有匹配<tr>的項
            MatchCollection matches = regex.Matches(content);
            foreach (Match item in matches)
            {
                //如果當前匹配項的下一個匹配項的值不為空
                if (!string.IsNullOrEmpty(item.NextMatch().Value))
                {
                    trContent = content.Substring(item.Index, item.NextMatch().Index - item.Index);
                }
                //最後一個<tr>的匹配項
                else
                {
                    trContent = content.Substring(item.Index, content.Length - item.Index);
                }
                //DataRow dr = sddt.NewRow();

                ResolveSDSJTd(trContent);

                //sddt.Rows.Add(dr);
            }

解析td資料

 private void ResolveSDSJTd(string trContent)
        {
            string patternChartBall = @"[1-9]\d{6}";
            Regex regex = new Regex(patternChartBall);
            MatchCollection rMatches = regex.Matches(trContent);
            string qihao = "";
            foreach (Match r in rMatches)
            {
                qihao = r.Value;
                break;
            }

            patternChartBall = "<td class=\"chartBall01\" width=18>";
            regex = new Regex(patternChartBall);
            rMatches = regex.Matches(trContent);
            List<int> redBoxList = new List<int>();

            foreach (Match r in rMatches)
            {
                int xx = int.Parse(trContent.Substring(r.Index + patternChartBall.Length, 1));
                redBoxList.Add(xx);
            }

            if (!string.IsNullOrEmpty(qihao))
            {
                DataRow[] dr = sddt.Select(string.Format("QiHao='{0}'", qihao));
                if (dr.Length > 0)
                {
                    dr[0]["R4"] = redBoxList[0];
                    dr[0]["R5"] = redBoxList[1];
                    dr[0]["R6"] = redBoxList[2];
                }
            }
        }

儲存資料

if (!Directory.Exists(tempPath))//判斷資料夾是否存在
                Directory.CreateDirectory(tempPath);//建立資料夾在根目錄下
            string _db = System.IO.Path.Combine(tempPath, "sddb.dll");
            SQLiteHelper helper = new SQLiteHelper(_db);
            OperResult oper = new OperResult();

            helper.ExecuteNonQuery(string.Format("drop table if exists {0}", sdtableName), _db);

            string msg = string.Format("create table if not exists {0} (\r\n", sdtableName);
            for (int i = 0; i < sddt.Columns.Count; i++)
            {
                msg += string.Format("{0} {1},\r\n", sddt.Columns[i].ColumnName, helper.TypeToSqliteType(sddt.Columns[i].DataType));
            }
            msg = msg.Remove(msg.LastIndexOf(",\r\n"), 3);
            msg += ")";

            oper = helper.ExecuteNonQuery(msg, _db);
            oper = helper.SaveDataTable(sddt, sdtableName);

以上即可完成對福彩3D資料的爬蟲,還能爬取福彩3D試機號,這些資料一些就能全部爬取完了,非常的快捷簡單方便。

雙色球走勢圖如下:

 

 

上一篇文章有介紹怎麼去實現雙色球走勢圖,這裡就不再過多介紹了,這一篇主要是介紹怎麼爬蟲雙色球和福彩3D資料。

詳細介紹:https://www.cnblogs.com/luoyuhao/p/13887935.html

後記

為了做好爬蟲資料和走勢圖,爬蟲技術只能為做好走勢圖是一個前提條件,兩個步驟是相輔相成的,現在這兩個技術都具備了,只是不斷完善技術才能做出更強大的走勢圖的網站。以上只是純技術交流和學習,歡迎大家一起留言交流,共同學習進步。