在上一篇爬蟲博客中,我們講述了應對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 ;
}
}
}
我們看一下打印出來的報文內容:
返回內容是亂碼,明顯某平臺做了巧妙的處理,直接請求這個url是無法得到我們想要的報文的。還有一些場景,比如說某些網頁裏會有類似【更多】這樣的按鈕,點擊後頁面纔會請求並渲染更多內容,這種也是無法通過直接請求該網頁爬取的。
通過chromedriver調用瀏覽器
下面我們通過C#調用chromedriver來控制瀏覽器訪問我們要爬取的頁面並實現爬取。首先通過nuget安裝Selenium庫:
注意如果安裝Selenium時選擇的是最新版的,需要將谷歌瀏覽器更新到最新,不然調用的時候會有異常
然後我們通過F12看下要爬取頁面的結構,看看我們要爬取的信息在哪些標籤裏,結果如下:
標題在class ='title-article’的h1中,發佈時間在class='time’的span中,博主在class='follow-nickName’的a標籤中,閱讀數在class='read-count’的span中,正文在id='article_content’的div中。
然後編碼調用谷歌瀏覽器訪問這個頁面並取到我們指定元素:
/// <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);
}
看下控制檯打印結果:
可以看到,已經成功通過調用Chrome爬取到了我們想要的信息。Selenium能做到的事情還遠不止如此,有興趣的可以自己研究下。後面也會繼續講Selenium的一些其它用法。
上一篇:C#攻克反爬蟲之代理IP爬取