.NET + Selenium + Chrome实现爬虫
一叶舟轻

.NET + Selenium + Chrome实现爬虫

一叶舟轻
2023-09-26 / 0 评论 / 21 阅读 / 正在检测是否收录...

代码案例

  1. 抓取目标(天气网)

    1. 列表: http://www.weather.com.cn/index/jqzdtqsj/index.shtml
    2. 以及列表下面的新闻详情页面
  2. 预览图

    1. file
    2. file

file


file
file



namespace teestWebCrawler
{
    public class Model
    {
        public class ZhongDaTianQiShiJian
        {
            public string index { get; set; }
            public string imgUrl { get; set; }
            public string jumpUrl { get; set; }
            public string dateTime { get; set; }
            public string title { get; set; }
            public string content { get; set; }
            public NewPage _newPage { get; set; }

            public class NewPage
            {
                public string articleTittle { get; set; }
                public string articleTimeSizeleft { get; set; }
                public string articleContent { get; set; }
            }
        }
    }
}


// Program.cs
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Edge;
using OpenQA.Selenium.Support.UI;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using static teestWebCrawler.Model;

Console.WriteLine("Hello, World!");

#region Chrome
//string driverServicePath = Path.Combine(Directory.GetCurrentDirectory(), "chromedriver_win32");
//ChromeDriverService service = ChromeDriverService.CreateDefaultService(driverServicePath);

////在平时开发过程中,我们其实没必要每次都打开浏览器,这速度非常缓慢,我们可以设置浏览器属性
//ChromeOptions options = new ChromeOptions();
//options.AddArgument("--headless");
//options.AddArgument("--no-sandbox");
//options.AddArgument("--incognito");
//options.AddArgument("--disable-gpu");
//options.AddArgument("--disable-gpu-program-cache");
//options.AddArgument("--log-level=3");

//ChromeDriver driver = new ChromeDriver(service, options);
//ChromeDriver driver = new ChromeDriver(service);
#endregion

#region Edge
string driverServicePath = Path.Combine(Directory.GetCurrentDirectory(), "edgedriver_win64");
EdgeDriverService service = EdgeDriverService.CreateDefaultService(driverServicePath);

//配置不打开浏览器
//EdgeOptions options = new EdgeOptions();
//options.AddArgument("--headless");
//options.AddArgument("--no-sandbox");
//options.AddArgument("--incognito");
//options.AddArgument("--disable-gpu");
//options.AddArgument("--disable-gpu-program-cache");
//options.AddArgument("--log-level=3");

//EdgeDriver driver = new EdgeDriver(service, options);

EdgeDriver driver = new EdgeDriver(service);
#endregion

testZhongDaTianQiShiJian();

// --------------------------------------------------------------------

#region 执行内容
//抓取近期重大天气事件
void testZhongDaTianQiShiJian()
{
    //要爬取的网页
    string url = "http://www.weather.com.cn/index/jqzdtqsj/index.shtml";

    //获取节点(没获取到会抛异常)
    Func<string, IWebElement, IWebElement> getElementHelp = (_CssSelector, _item) =>
    {
        try
        {
            return _item.FindElement(By.CssSelector("img"));
        }
        catch
        {
            return null;
        }
    };

    //抓取新闻详情页面
    Action<IWebElement, ZhongDaTianQiShiJian> getLinkContent = (_item, _data) =>
    {
        Console.WriteLine("\n准备抓取内容页");

        //点击列表
        _item.FindElement(By.CssSelector("dt")).Click();
        Thread.Sleep(1500);//等一下

        //获取当前窗口句柄
        string currentHandle = driver.CurrentWindowHandle;
        //获得所有的窗口句柄,如果不是currentHandle,则进入
        ReadOnlyCollection<string> currentHandleAll = driver.WindowHandles;
        string LinkCurrentHandle = "";
        for (int i = 0; i < currentHandleAll.Count; i++)
        {
            if (!currentHandle.Equals(currentHandleAll[i]))
            {
                LinkCurrentHandle = currentHandleAll[i];
                break;
            }
        }
        //切换到这个窗口
        driver.SwitchTo().Window(LinkCurrentHandle);

        //标题
        string articleTittle = driver.FindElement(By.CssSelector(".articleBox .articleTittle")).Text;
        //来源
        string articleTimeSizeleft = driver.FindElement(By.CssSelector(".articleBox .articleTimeSizeleft")).Text;

        //内容
        var listP = driver.FindElements(By.CssSelector(".articleBox .articleBody>p"));
        //重新组装成Markdown
        StringBuilder sbMK = new StringBuilder();
        foreach (var item in listP)
        {
            var img = getElementHelp("img", item);
            var strong = getElementHelp("strong", item);
            if (img != null)
            {
                string src = img.GetAttribute("src");
                string alt = img.GetAttribute("alt");
                sbMK.AppendLine($" ![{alt}]({src}) ");
            }
            else if (strong != null)
            {
                sbMK.AppendLine($"### {strong.Text}");
            }
            else
            {
                sbMK.AppendLine(item.Text);
            }
        }

        _data._newPage = new ZhongDaTianQiShiJian.NewPage
        {
            articleTittle = articleTittle,
            articleTimeSizeleft = articleTimeSizeleft,
            articleContent = sbMK.ToString(),
        };

        //回到列表窗口
        driver.SwitchTo().Window(currentHandle);
    };

    List<ZhongDaTianQiShiJian> listShiJian = new List<ZhongDaTianQiShiJian>();

    //抓取列表页面
    Action getPageContent = null;
    getPageContent = () =>
    {
        string current = driver.FindElement(By.CssSelector(".content_l>.fanye .current")).Text;
        Console.WriteLine($"=============当前正在抓取 [第{current}页]==========\n");

        //获取到新闻列表
        ReadOnlyCollection<IWebElement> sky = driver.FindElements(By.CssSelector(".content_l>dl"));
        Console.WriteLine($"共获取{sky.Count}个新闻");

        int index = 0;
        foreach (var item in sky)
        {
            //测试(每⻚只取第⼀个)
            if (index != 0)
                continue;

            index++;
            string _idxTxt = $"{current}_{index}";
            string imgUrl = item.FindElement(By.CssSelector("dt>a>img")).GetAttribute("src");
            string jumpUrl = item.FindElement(By.CssSelector("dt>a")).GetAttribute("href");
            string dateTime = item.FindElement(By.CssSelector("dd>h3>span")).Text;
            string title = item.FindElement(By.CssSelector("dd>h3>a")).Text;
            string content = item.FindElement(By.CssSelector("dd>p")).Text;

            ZhongDaTianQiShiJian _data = new ZhongDaTianQiShiJian
            {
                index = _idxTxt,
                imgUrl = imgUrl,
                jumpUrl = jumpUrl,
                dateTime = dateTime,
                title = title,
                content = content
            };

            //抓取内容页
            getLinkContent(item, _data);

            //将数据存储起来
            listShiJian.Add(_data);
        }

        #region 下一页
        //按钮 "下一页" 是否还可以点击
        string disabled = driver.FindElement(By.CssSelector(".content_l>.fanye>.manu .disabled")).Text;
        Console.WriteLine("disabled:" + disabled);
        bool isdisabled = disabled == "下一页";
        if (!isdisabled)
        {
            try
            {
                //点击下一页
                driver.FindElement(By.CssSelector(".content_l>.fanye>.manu a:last-of-type")).Click();
                Console.WriteLine($"[{current}] 点击下一页");

                //Selenium "显示等待",等待页面加载完成并满足设定的条件,若等待超过设定时间会抛出异常
                WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
                //等待页面上的元素加载完成
                IWebElement? element = wait.Until((d) =>
                {
                    try
                    {
                        return driver.FindElement(By.CssSelector(".content_l>h2"));
                    }
                    catch (Exception ex)
                    {
                        return null;
                    }
                });

                if (element != null)
                {
                    Console.WriteLine($"下一页 [{current}] 继续加载");
                    getPageContent();
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine($"[{current}] 加载“下一页”时出错,异常:", ex.Message);
            }
        }
        else
        {
            Console.WriteLine($"[{current}] 没有更多了");
        }
        #endregion
    };


    //打开网页
    driver.Navigate().GoToUrl(url);

    Console.WriteLine("** 开始Start **");

    //开始执行
    Console.WriteLine("getPageContent(),递归,GO");
    getPageContent();

    Console.WriteLine("\n*******************************************\n");
    Console.WriteLine("打印结果");
    //打印列表
    foreach (ZhongDaTianQiShiJian item in listShiJian)
    {
        Console.WriteLine($"\n【{item.index}】");
        Console.WriteLine($"title:{item.title}");
        Console.WriteLine($"dateTime:{item.dateTime}");
        Console.WriteLine($"imgUrl:{item.imgUrl}");
        Console.WriteLine($"jumpUrl:{item.jumpUrl}");
        Console.WriteLine($"content:{item.content}");
        Console.WriteLine("-----------------[新闻详情]--------------------");
        Console.WriteLine($"articleTittle:{item._newPage.articleTittle}");
        Console.WriteLine($"articleTimeSizeleft:{item._newPage.articleTimeSizeleft}");
        Console.WriteLine($"articleContent:{item._newPage.articleContent}");
    }

    //释放资源、关闭浏览器
    driver.Dispose();
    driver.Quit();
    Console.WriteLine("** 结束End **");
}
#endregion

查看结果

Hello, World!
Starting Microsoft Edge WebDriver 118.0.2088.76 (d3ddcf1d51d5981b1862597e6ea77f06d265a377) on port 64378
To submit feedback, report a bug, or suggest new features, please visit https://github.com/MicrosoftEdge/EdgeWebDriver

Only local connections are allowed.
Please see https://aka.ms/WebDriverSecurity for suggestions on keeping Microsoft Edge WebDriver safe.

Microsoft Edge WebDriver was started successfully.
[30768:30380:1028/194629.380:ERROR:policy_logger.cc(154)] :components\enterprise\browser\controller\chrome_browser_cloud_management_controller.cc(163) Cloud management controller initialization aborted as CBCM is not enabled.
[30768:30380:1028/194629.405:ERROR:assistance_home_client.cc(32)] File path C:\Users\liush\AppData\Local\Temp\scoped_dir20464_609892831\Default

DevTools listening on ws://127.0.0.1:64381/devtools/browser/f03838e5-a03a-480a-a829-bf59250e1fc1
** 开始Start **
getPageContent(),递归,GO
=============当前正在抓取 [第1页]==========

共获取20个新闻

准备抓取内容页
disabled:上一页
[1] 点击下一页
下一页 [1] 继续加载
=============当前正在抓取 [第2页]==========

共获取20个新闻

准备抓取内容页
[30768:30380:1028/194641.397:ERROR:fallback_task_provider.cc(124)] Every renderer should have at least one task provided by a primary task provider. If a "Renderer" fallback task is shown, it is a bug. If you have repro steps, please file a new bug and tag it as a dependency of crbug.com/739782.
[30768:30380:1028/194642.700:ERROR:smartscreen_dns_resolver.cc(110)] SmartScreenDnsResolver::OnComplete Error: -7 DidTimeOut: 1 URL: http://www.weather.com.cn/index/2023/10/3657061.shtml
[30768:30380:1028/194642.700:ERROR:smartscreen_dns_resolver.cc(110)] SmartScreenDnsResolver::OnComplete Error: -7 DidTimeOut: 1 URL: http://www.weather.com.cn/index/jqzdtqsj/index_2.shtml
disabled:下一页
[2] 没有更多了

*******************************************

打印结果

【1_1】
title:广东广西等地本周末降雨增强局地有大暴雨 中东部气温持续偏暖
dateTime:2023-10-28 07:53:21
imgUrl:http://i.weather.com.cn/images/cn/news/2023/10/28/20231028075735311E65BECBEAE1430489BEED116144F5.jpg
jumpUrl:http://www.weather.com.cn/index/2023/10/3662192.shtml
content:本周末(10月28日至29日)广东、广西等地降雨将会增强,其中明天部分地区有暴雨,局地大暴雨。
-----------------[新闻详情]--------------------
articleTittle:广东广西等地本周末降雨增强局地有大暴雨 中东部气温持续偏暖
articleTimeSizeleft:2023-10-28 07:53:21 来源: 中国天气网
articleContent:中国天气网讯 本周末(10月28日至29日)广东、广西等地降雨将会增强,其中明天部分地区有暴雨,局地大暴雨。除 华南地区有较强降雨外,中东部大部地区天气晴朗,气温维持较常年同期偏高水平,11月初华北地区到长江中下游沿线或现同期少见的暖热。
广东等地降雨增强 部分地区有暴雨
昨天,北方大部秋高气爽,降水稀少,雨水主要出现在江南、华南等地。实况监测数据显示,广西东南部、广东西南部、福建南部、海南岛等地部分地区出现大到暴雨,广西玉林、广东茂名局地大暴雨。
今天开始,随着偏东气流加强,华南雨势明显增强。中央气象台预计,新疆西北部、西藏东部、川西高原西北部等地的部分地区有小到中雪或雨夹雪;云南南部、广西中部和南部、广东西南部、海南岛、台湾岛等地的部分地区有中雨,局地大雨。
 ![bqdt](http://i.weather.com.cn/images/cn/news/2023/10/28/1698451010287006104.jpg)
明天,新疆北部、西藏中南部等地的部分地区有小到中雪或雨夹雪,其中新疆阿勒泰等地有大雪,部分地区暴雪;云南南部、广西南部和东部、广东西部、海南岛北部等地有中到大雨,其中广西东南部、广东西南部的部分地区有暴雨,局地大暴雨。
 ![bqdt](http://i.weather.com.cn/images/cn/news/2023/10/28/1698451034578021575.jpg)
后天,新疆北部、内蒙古东北部、黑龙江西部、西藏中东部、川西高原北部等地的部分地区有小到中雪或雨夹雪,其中新疆阿勒泰等地有大雪,部分地区暴雪;四川盆地西南部、云南南部、广东雷州半岛、海南岛等地的部分地区有中雨,局地大雨。
 ![bqdt](http://i.weather.com.cn/images/cn/news/2023/10/28/1698451046028066539.jpg)
气象部门提醒,本周末华南进入本次降雨最强时段,并且还会伴随强对流天气,公众需注意防范短时强降雨、雷暴大风,同时防范强降雨可能引发的次生灾害。
11月初多地或暖到破纪录 今起华北黄淮霾天气发展
本周以来,中东部虽然也受到冷空气影响,但气温仍普遍处在较常年同期偏高水平。预计一直到本月底,冷空气活动较弱,大部地区将持续偏暖,其中华北地区到长江中下游沿线温暖程度或是同期少见的,30日起多地最高气温可能接近30℃。
大城市中,太原、西安、石家庄、济南等地在11月初可能会暖到打破当地11月最高气温纪录。像济南,11月1日最高气温或将达29℃,最低气温也可能超过20℃。
同时,由于冷空气活动弱,华北、黄淮等地静稳天气形势建立,今天起霾天气又将发展。预计10月28日至11月2日,华北中南部、黄淮等 地大气扩散条件转差,区域大部有轻到中度霾天气,华北中南部局地有重度霾。11月3日起,受冷空气影响,上述地区大气扩散条件转好 ,霾天气减弱消散。公众需注意防范。


【2_1】
title:节后首个工作日华南华西等地降水持续 中东部多地气温将创新低
dateTime:2023-10-07 07:50:39
imgUrl:http://i.weather.com.cn/images/cn/news/2023/10/07/20231007080117FD61CC7F4B1717B37742CFE8A8C23D0A.jpg
jumpUrl:http://www.weather.com.cn/index/2023/10/3657061.shtml
content:今天(10月7日)是节后开工首日,我国降水主要集中在华南、华西、东北等地。同时,冷空气将继续南下,中东部多地气温将创今年立秋以来新低。
-----------------[新闻详情]--------------------
articleTittle:广东广西等地本周末降雨增强局地有大暴雨 中东部气温持续偏暖
articleTimeSizeleft:2023-10-28 07:53:21 来源: 中国天气网
articleContent:中国天气网讯 本周末(10月28日至29日)广东、广西等地降雨将会增强,其中明天部分地区有暴雨,局地大暴雨。除 华南地区有较强降雨外,中东部大部地区天气晴朗,气温维持较常年同期偏高水平,11月初华北地区到长江中下游沿线或现同期少见的暖热。
广东等地降雨增强 部分地区有暴雨
昨天,北方大部秋高气爽,降水稀少,雨水主要出现在江南、华南等地。实况监测数据显示,广西东南部、广东西南部、福建南部、海南岛等地部分地区出现大到暴雨,广西玉林、广东茂名局地大暴雨。
今天开始,随着偏东气流加强,华南雨势明显增强。中央气象台预计,新疆西北部、西藏东部、川西高原西北部等地的部分地区有小到中雪或雨夹雪;云南南部、广西中部和南部、广东西南部、海南岛、台湾岛等地的部分地区有中雨,局地大雨。
 ![bqdt](http://i.weather.com.cn/images/cn/news/2023/10/28/1698451010287006104.jpg)
明天,新疆北部、西藏中南部等地的部分地区有小到中雪或雨夹雪,其中新疆阿勒泰等地有大雪,部分地区暴雪;云南南部、广西南部和东部、广东西部、海南岛北部等地有中到大雨,其中广西东南部、广东西南部的部分地区有暴雨,局地大暴雨。
 ![bqdt](http://i.weather.com.cn/images/cn/news/2023/10/28/1698451034578021575.jpg)
后天,新疆北部、内蒙古东北部、黑龙江西部、西藏中东部、川西高原北部等地的部分地区有小到中雪或雨夹雪,其中新疆阿勒泰等地有大雪,部分地区暴雪;四川盆地西南部、云南南部、广东雷州半岛、海南岛等地的部分地区有中雨,局地大雨。
 ![bqdt](http://i.weather.com.cn/images/cn/news/2023/10/28/1698451046028066539.jpg)
气象部门提醒,本周末华南进入本次降雨最强时段,并且还会伴随强对流天气,公众需注意防范短时强降雨、雷暴大风,同时防范强降雨可能引发的次生灾害。
11月初多地或暖到破纪录 今起华北黄淮霾天气发展
本周以来,中东部虽然也受到冷空气影响,但气温仍普遍处在较常年同期偏高水平。预计一直到本月底,冷空气活动较弱,大部地区将持续偏暖,其中华北地区到长江中下游沿线温暖程度或是同期少见的,30日起多地最高气温可能接近30℃。
大城市中,太原、西安、石家庄、济南等地在11月初可能会暖到打破当地11月最高气温纪录。像济南,11月1日最高气温或将达29℃,最低气温也可能超过20℃。
同时,由于冷空气活动弱,华北、黄淮等地静稳天气形势建立,今天起霾天气又将发展。预计10月28日至11月2日,华北中南部、黄淮等 地大气扩散条件转差,区域大部有轻到中度霾天气,华北中南部局地有重度霾。11月3日起,受冷空气影响,上述地区大气扩散条件转好 ,霾天气减弱消散。公众需注意防范。

** 结束End **

F:\dome\teestWebCrawler\teestWebCrawler\bin\Debug\net6.0\teestWebCrawler.exe (进程 18048)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
0

评论 (0)

取消