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爬取

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章