C#实现爬取哈希表博客文章

2018年7月8日18:20:202 XXM

Begin

这个简单的爬虫应用是在入职哈希表前一天晚上写的,代码写的有点low,是通过正则表达式和截取字符串来进行对内容的爬取(非常原始的办法).

效果图

QQ截图20180708182301.png

首先定义了一个类Grab里面的方法主要用来对网页内容进行获取,以及编码解码.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;

namespace GrabBlog
{
    class Grab
    {
        public string GetHtmlCode(string url)
        {
            string htmlCode;
            HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
            webRequest.Timeout = 30000;
            webRequest.Method = "GET";
            webRequest.UserAgent = "Mozilla/4.0";
            webRequest.Headers.Add("Accept-Encoding", "gzip, deflate");
            HttpWebResponse webResponse = (System.Net.HttpWebResponse)webRequest.GetResponse();
            if (webResponse.ContentEncoding.ToLower() == "gzip")//如果使用了GZip则先解压  
            {
                using (System.IO.Stream streamReceive = webResponse.GetResponseStream())
                {
                    using (var zipStream =
                        new System.IO.Compression.GZipStream(streamReceive, System.IO.Compression.CompressionMode.Decompress))
                    {
                        Encoding enc = GetEncoding(url);
                        using (StreamReader sr = new System.IO.StreamReader(zipStream, enc))
                        {
                            htmlCode = sr.ReadToEnd();
                        }
                    }
                }
            }
            else
            {
                using (System.IO.Stream streamReceive = webResponse.GetResponseStream())
                {
                    Encoding enc = GetEncoding(url);
                    using (System.IO.StreamReader sr = new System.IO.StreamReader(streamReceive, enc))
                    {
                        htmlCode = sr.ReadToEnd();
                    }
                }
            }

            return htmlCode;
        }
        public Encoding GetEncoding(string strurl)
        {
            string urlToCrawl = strurl;
            //generate http request  
            if (urlToCrawl != null && urlToCrawl != "")
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(urlToCrawl);
                //use GET method to get url's html  
                req.Method = "GET";
                req.Accept = "*/*";
                req.Headers.Add("Accept-Language", "zh-cn,en-us;q=0.5");
                req.ContentType = "text/xml";
                //use request to get response  
                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                Encoding enc;
                try
                {
                    if (resp.CharacterSet != "ISO-8859-1")
                        enc = Encoding.GetEncoding(resp.CharacterSet);
                    else
                        enc = Encoding.UTF8;
                }
                catch
                {
                    // *** Invalid encoding passed  
                    enc = Encoding.UTF8;
                }
                string sHTML = string.Empty;
                using (StreamReader read = new StreamReader(resp.GetResponseStream(), enc))
                {
                    sHTML = read.ReadToEnd();
                    Match charSetMatch = Regex.Match(sHTML, "charset=(?<code>[a-zA-Z0-9\\-]+)", RegexOptions.IgnoreCase);
                    string sChartSet = charSetMatch.Groups["code"].Value;
                    //if it's not utf-8,we should redecode the html.  
                    if (!string.IsNullOrEmpty(sChartSet) && !sChartSet.Equals("utf-8", StringComparison.OrdinalIgnoreCase))
                    {
                        enc = Encoding.GetEncoding(sChartSet);
                    }
                }
                return enc;
            }
            return Encoding.Default;
        }  
    }
}

GetHtmlCode方法 主要用于获取内容,GetEncoding方法主要用于编码解码.

对博客进行爬取的具体代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;

namespace GrabBlog
{
    public partial class Form1 : Form
    {
        public static string[] urlArr;//链接
        string[] timeArr;//时间
        string[] titleArr;//标题
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Grab grab = new Grab();
            //获取网页全部资源
            String html = grab.GetHtmlCode("https://www.haxibiao.com/user/14").Trim().Replace("\n", "").Replace("\r", "").Replace("\t", "");
            //获取用户名
            string feature1 = mid(html, "<a class=\"headline nickname\" href=\"/v2/user\">", "<");
            string userName = feature1.Trim();
            //提取大范围特征并对代码进行处理
            html = mid(html, "<p class=\"tab-pane fade in active\" id=\"dongtai\" role=\"tabpanel\">", "<ul class=\"pagination\">");
            html = html.Replace(" ", "");
            //resource
            string reg = "";//正则表达式
            MatchCollection Datereward = null;
            timeArr=new string[10];//时间
            titleArr=new string[10];//标题
            urlArr = new string[10];//链接
            int i = 0;//初始化索引
            //时间获取Begin
            reg = @"<spanclass=""time"">(?<time>.*?)</span>";
            Datereward = Regex.Matches(html, reg);
            foreach (Match item in Datereward) 
            { 
                timeArr[i]=item.Groups["time"].ToString();
                i++;
            }
            //时间End
            //标题获取Begin
            reg = @"<aclass=""headlinepaper-title""href=""(?<url>.*?)""target=""_blank""><span>(?<title>.*?)</span></a>";
            i = 0;//重新初始化下标
            Datereward = Regex.Matches(html, reg);
            foreach (Match item in Datereward)
            {
                titleArr[i] = item.Groups["title"].ToString();
                urlArr[i] = item.Groups["url"].ToString();
                i++;
            }
            //标题End
            //放进datagridView中 Begin
            for (i = 0; i < 10; i++) 
            {
                int index = dgw_BlogData.Rows.Add();//获取当前行
                dgw_BlogData.Rows[index].Cells[0].Value = userName;
                dgw_BlogData.Rows[index].Cells[1].Value = timeArr[i];
                dgw_BlogData.Rows[index].Cells[2].Value = titleArr[i];
                dgw_BlogData.Rows[index].Cells[3].Value = "查看详情";
                dgw_BlogData.Rows[index].Cells[3].Style.ForeColor = Color.Blue;//设置详情颜色
            }
                //end
        }
        private string mid(string istr, string startString, string endString)
        {
            int iBodyStart = istr.IndexOf(startString, 0);    //开始位置
            if (iBodyStart == -1)
                return null;
            iBodyStart += startString.Length;       //第一次字符位置起的长度
            int iBodyEnd = istr.IndexOf(endString, iBodyStart);   //第二次字符在第一次字符位置起的首次位置
            if (iBodyEnd == -1)
                return null;
            iBodyEnd += endString.Length;        //第二次字符位置起的长度
            string strResult = istr.Substring(iBodyStart, iBodyEnd - iBodyStart - 1);
            return strResult;
        }

        private string mid(string istr, string startString, string endString, out int iBodyEnd)
        {
            //初始化out参数,否则不能return
            iBodyEnd = 0;

            int iBodyStart = istr.IndexOf(startString, 0);    //开始位置
            if (iBodyStart == -1)
                return null;
            iBodyStart += startString.Length;       //第一次字符位置起的长度
            iBodyEnd = istr.IndexOf(endString, iBodyStart);   //第二次字符在第一次字符位置起的首次位置
            if (iBodyEnd == -1)
                return null;
            iBodyEnd += endString.Length;        //第二次字符位置起的长度
            string strResult = istr.Substring(iBodyStart, iBodyEnd - iBodyStart - 1);
            return strResult;
        }

        private void dgw_BlogData_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 3) //详情按钮被点击的时候
            {
                int currentRows = e.RowIndex;//获取当前被点击行
                TextWindow tw = new TextWindow();
                TextWindow.title = titleArr[currentRows];
                TextWindow.url = urlArr[currentRows];
                tw.Show();
            }
        }
    }
}


End

日记本

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

赞赏支持
被以下专题收入,发现更多相似内容