c# winform 爬虫 小工具开发

c#爬虫窗体Demo

开发工具:vs2017,sql server 2014
框架版本:.net framework 4.6.1
开发模式:三层、orm PetaPoco

思路:
爬虫最为关键的一环就是读取网页的源码,其核心内容也是对网页源码的处理,因此获取到完整的网页源码是极为重要的(或者是要爬取的信息列表源码)。通过对网页源码进行字符串的处理,以便于获取需要的字段信息。

1.分析网页网址
例:https://www.shicimingju.com/shicimark/aiqingshi_1_0__0.html
这个网址翻页时会发生变动如果是第6页,网址为:
https://www.shicimingju.com/shicimark/aiqingshi_6_0__0.html
这时候,写一个循环拼接网址即可

2.分析网页(通过webBrowser加载网页)
(1).首先获取详情页的网址链接,主要是对a标签的处理,并拼接出一个完整的详情页网址,入库
注:详情页指的是,比如逛淘宝时,你点进去查看的就是商品的详情
(2).通过webBrowser循环加载第一步收入的网址,并提取需要的信息(主要是通过对字符串的截取实现)

实现过程
1.创建一个winform窗体程序,使用webBrowser控件c# winform 爬虫 小工具开发_第1张图片
页面加载实例代码

 //阻止网页js弹窗
 webBrowser1.ScriptErrorsSuppressed = true;
//加载网页   
 webBrowser1.Navigate("https://www.shicimingju.com/shicimark/aiqingshi_1_0__0.html");
//获取当前webBrowser加载的网页源码
string htmlString = webBrowser1.Document.Body.OuterHtml;

因为webBrowser控件的内核是ie,所以对网页的兼容性比较差,好多网址在这个控件中加载时,会有js的错误弹窗,影响程序运行,所以需要阻止弹窗的弹出。

2.获取详情页链接
我们在抓取链接时,抓取有效链接也是十分重要的,这样做有利于数据规范。一般详情页的链接都是有规律的,包含通用的关键字,比如list(https://www.shicimingju.com/chaxun/list/3227.html)
(1).使用正则表达式提取a标签的href
优点,通用性比较强(对于多个网站来说,可适用于多个网站的a标签链接的提取)
缺点,因各个网站的差异性,提取的链接可能不准确
(2).使用字符串截取的方式提取a标签的href
优点,截取比较准确(指定网站)
缺点,通用性较差

代码示例(我这里采用的是字符串截取的方式)

string htmlString = webBrowser1.Document.Body.OuterHtml;

string blUrl = "";

string[] collArray = Regex.Split(htmlString, "", RegexOptions.IgnoreCase);


for (int i = 0; i < collArray.Length - 1; i++)
{
    try
    {
        //提取a标签
        blUrl = HtmlUnscramble.GetValue(collArray[i], "href=\"", "\"");
        if (blUrl == "") blUrl = HtmlUnscramble.GetValue(collArray[i], "href='", "'");
        if (blUrl == "") blUrl = HtmlUnscramble.GetValue(collArray[i], "href=", " ");

        if (blUrl.IndexOf("(") > -1 || blUrl.IndexOf("javascript") > -1 || blUrl.Length < 5) continue;

        if (blUrl.Substring(0, 2) == "//") blUrl = "http:" + blUrl;

        if (blUrl.Substring(0, 1) == "/" || blUrl.Substring(0, 1) == ".") blUrl = urlAdder + blUrl;

        if (!blUrl.Substring(0, 5).Contains("http") && blUrl.Substring(0, 1) != "/" && blUrl.Substring(0, 1) != ".")
        {
            blUrl = urlAdder + "/" + blUrl;
        }

        if (blUrl.IndexOf(".com//") > -1) blUrl = blUrl.Replace(".com//", ".com/");

        if (blUrl.IndexOf(".cn//") > -1) blUrl = blUrl.Replace(".cn//", ".cn/");

        if (blUrl.IndexOf(".net//") > -1) blUrl = blUrl.Replace(".net//", ".net/");

        blUrl = blUrl.Replace("&", "");


        if (!blUrl.Contains(urlAdderKey)) continue;

        string[] productKey = urlAdderKey.Split(';');
        bool blProductKey = false;
        for (int k = 0; k < productKey.Length; k++)
        {
            if (blUrl.Contains(productKey[k])) { blProductKey = true; };
        }
        //符合关键字入库
        if (blProductKey)
        {
            int hrefcount = GSDA.GetGushi(blUrl);
            if (hrefcount==0)
            {
                GuShiInfo guShiInfo = new GuShiInfo
                {
                    Href = blUrl
                };
                GSDA.InGushi(guShiInfo);
            }
        }
    }
    catch 
    {
        
    }
}

3.获取详情页数据信息
(1).加载详情页面

加载示例代码(这里加载时长我设置了1分钟,目的是确保网页源码的完整性)

#region Loading
/// 
/// 根据网址加载网页
/// 
/// 网址
public void Loading(string url)
{

    bool loading = true;  //表示正在加载
    webBrowser1.Navigate(url);
    DateTime dtime = DateTime.Now.AddMinutes(1);

    while (loading)
    {
        Application.DoEvents();//等待本次加载完毕才执行下次循环.        

        if (DateTime.Now > dtime)
        {
            loading = false;
        }
    }

    if (loading == false)
    {
        Application.DoEvents();//等待本次加载完毕才执行下次循环.   
    }

}

#endregion

(2).进行字符串处理,提取有效数据

数据提取代码示例(我这里使用的字符串截取的方式,也可使用正则)

IList<GuShiInfo> IGI = GSDA.GetAllGushi();
for (int i = 0; i < IGI.Count; i++)
{
	  Loading(IGI[i].Href);
	
	  html = webBrowser1.Document.Body.OuterHtml.ToLower();
	
	  title = HtmlUnscramble.GetValue(html, "

", "

"
); concent = HtmlUnscramble.GetValue(html, "
", "
"
); authorandyears = Regex.Split(HtmlUnscramble.GetValue(html, "
", "
"
,false), ", RegexOptions.IgnoreCase); years = HtmlUnscramble.ClearStyle(authorandyears[0]); author = HtmlUnscramble.GetValue(authorandyears[1], ">", "<"); shangxi = HtmlUnscramble.GetValue(html, "
作品赏析
"
, "
"); IGI[i].Html = html.Replace("'",""); IGI[i].Title = title; IGI[i].Author = author; IGI[i].ShangXi = shangxi; IGI[i].Years = years; IGI[i].Concent = concent; IGI[i].State = 1; GSDA.UpdateGuShi(IGI[i]); Random random = new Random(); int seconds = random.Next(1, 7) * 1000; Thread.Sleep(seconds); }

4.注意事项
(1).注意控制网页抓取速率,访问太频繁,会被网站反扒检测到,ip会被封掉。因此控制页面时长就很重要了!
(2).如果网站有json源数据,抓取这个也是可以的,后期会出一个json数据抓取案例。
(3).webBrowser 由于是ie内核,所以网站兼容性很差。可以使用谷歌内核的类似插件,如CefSharp,使用nuget包下载即可。后期会出一个简单的教程使用CefSharp制作爬虫

你可能感兴趣的:(爬虫,c#,开发语言)