C#攻克反爬虫之谷歌浏览器调用

在上一篇爬虫博客中,我们讲述了应对IP访问限制的策略,即爬取代理IP并不断改变代理的方式。但是某些网站不仅在访问时做了限制,而且在返回网页时也做了巧妙的处理,比如在页面加载时调用js动态请求内容等。这种情况就不是简单的发出一个get请求可以爬取的了,这个时候可能就需要调用谷歌浏览器来实现爬取。本篇我们介绍通过C#调用谷歌浏览器来实现动态信息爬取。

普通爬虫遭遇的困境

假如我们要爬取某博客页面的详细信息,如标题,正文,作者,发布时间,阅读数等等。我们的第一思路是对这个页面的url发送一个get请求,对返回的网页报文通过xpath解析我们需要的信息。下面以一个博客详情页面为例:C#攻克反爬虫之代理IP爬取

    class Program
    {
        static void Main(string[] args)
        {
            BasicalMothed("https://blog.csdn.net/Leaderxin/article/details/102764234"); //调用原始方法
            Console.Read();
        }
        /// <summary>
        /// 这个我们普通的爬虫思路,通过请求url返回报文爬取
        /// </summary>
        static void BasicalMothed(string url)
        {
            HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
            if (req == null)
                return;
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Encoding bin = Encoding.GetEncoding("UTF-8");
            using (StreamReader sr = new StreamReader(resp.GetResponseStream(), bin))
            {
                string str = sr.ReadToEnd();
                Console.WriteLine(str.ToString());
                //在这里通过xpath对str的内容进行解析并存储
                return ;
            }
        }
    }

我们看一下打印出来的报文内容:
C#爬虫
返回内容是乱码,明显某平台做了巧妙的处理,直接请求这个url是无法得到我们想要的报文的。还有一些场景,比如说某些网页里会有类似【更多】这样的按钮,点击后页面才会请求并渲染更多内容,这种也是无法通过直接请求该网页爬取的。

通过chromedriver调用浏览器

下面我们通过C#调用chromedriver来控制浏览器访问我们要爬取的页面并实现爬取。首先通过nuget安装Selenium库:

注意如果安装Selenium时选择的是最新版的,需要将谷歌浏览器更新到最新,不然调用的时候会有异常

Selenium
然后我们通过F12看下要爬取页面的结构,看看我们要爬取的信息在哪些标签里,结果如下:
标题在class ='title-article’的h1中,发布时间在class='time’的span中,博主在class='follow-nickName’的a标签中,阅读数在class='read-count’的span中,正文在id='article_content’的div中。
C#爬虫
然后编码调用谷歌浏览器访问这个页面并取到我们指定元素:

        /// <summary>
        /// 通过Selenium调用谷歌浏览器来爬取
        /// </summary>
        /// <param name="url"></param>
        static void SeleniumMothed(string url)
        {
            //启动谷歌浏览器
            IWebDriver selenium = new ChromeDriver();
            //浏览器跳转到我们要爬取的url
            selenium.Navigate().GoToUrl(url);
            //确保页面内容已加载完成
            while (string.IsNullOrEmpty(selenium.Title))
            {
                Task.Delay(100).GetAwaiter().GetResult();
            }
            
            
            //取到标题信息,通过css选择器
            var title = selenium.FindElement(By.CssSelector("h1.title-article")).Text; 
            //发布时间
            var time = selenium.FindElement(By.CssSelector("span.time")).Text;
            //博主名
            var name = selenium.FindElement(By.CssSelector("a.follow-nickName")).Text;
            //阅读数
            var nums = selenium.FindElement(By.CssSelector("span.read-count")).Text;
            //正文,由于id固定,我们直接用id选择器获取
            var content = selenium.FindElement(By.Id("article_content")).Text;
            Console.WriteLine("标题:"+title);
            Console.WriteLine("发布时间:"+time);
            Console.WriteLine("博主名:"+name);
            Console.WriteLine("阅读数:"+nums);
            Console.WriteLine("正文:"+content);
        }

看下控制台打印结果:
C# Selenium
可以看到,已经成功通过调用Chrome爬取到了我们想要的信息。Selenium能做到的事情还远不止如此,有兴趣的可以自己研究下。后面也会继续讲Selenium的一些其它用法。
上一篇:C#攻克反爬虫之代理IP爬取

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要检查谷歌浏览器是否处于全屏状态,你可以使用C#的WinForms来进行操作。在WinForms中,你可以使用Windows API函数来获取浏览器的窗口状态。 首先,你需要导入`user32.dll`库,并声明`GetWindowPlacement`函数,该函数用于获取窗口的位置和状态信息。代码示例如下: ```csharp using System; using System.Runtime.InteropServices; public class Program { [DllImport("user32.dll")] public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); [Serializable] [StructLayout(LayoutKind.Sequential)] public struct WINDOWPLACEMENT { public int length; public int flags; public int showCmd; public POINTAPI ptMinPosition; public POINTAPI ptMaxPosition; public RECT rcNormalPosition; } [Serializable] [StructLayout(LayoutKind.Sequential)] public struct POINTAPI { public int x; public int y; } [Serializable] [StructLayout(LayoutKind.Sequential)] public struct RECT { public int left; public int top; public int right; public int bottom; } public static void Main() { IntPtr chromeHandle = IntPtr.Zero; // 谷歌浏览器的窗口句柄 // 根据窗口标题查找谷歌浏览器的句柄 chromeHandle = FindWindowByCaption(IntPtr.Zero, "Google Chrome"); if (chromeHandle != IntPtr.Zero) { WINDOWPLACEMENT placement = new WINDOWPLACEMENT(); placement.length = Marshal.SizeOf(placement); // 获取窗口状态 GetWindowPlacement(chromeHandle, ref placement); if (placement.showCmd == 3) // 全屏状态的showCmd值为3 { Console.WriteLine("谷歌浏览器处于全屏状态"); } else { Console.WriteLine("谷歌浏览器不处于全屏状态"); } } else { Console.WriteLine("未找到谷歌浏览器窗口"); } } [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)] static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName); } ``` 以上代码会检查谷歌浏览器的窗口状态,并输出结果。如果谷歌浏览器处于全屏状态,会输出"谷歌浏览器处于全屏状态",否则输出"谷歌浏览器不处于全屏状态"。请注意,此代码假设你已经打开了谷歌浏览器并且它的窗口标题为"Google Chrome"。如果你使用的是不同的浏览器或窗口标题,请相应地修改代码中的窗口标题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值