QQ登录

只需要一步,快速开始

APP扫码登录

只需要一步,快速开始

手机号码,快捷登录

手机号码,快捷登录

查看: 3477|回复: 0

[C#/.NET] C#+Selenium+ChromeDriver 爬取网页模拟真实用户浏览行为

[复制链接]

等级头衔

积分成就    金币 : 2841
   泡泡 : 1516
   精华 : 6
   在线时间 : 1294 小时
   最后登录 : 2024-11-21

丰功伟绩

优秀达人突出贡献荣誉管理论坛元老

联系方式
发表于 2021-11-10 10:31:35 | 显示全部楼层 |阅读模式
一、背景8 v- D/ I* D: d) q! p0 V7 f7 |9 h
        Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。而对于爬虫来说,使用Selenium操控浏览器来爬取网上的数据那么肯定是爬虫中的杀手武器。这里,我将介绍selenium + 谷歌浏览器的一般使用。
7 \$ a9 j7 _; g0 V+ j1 \$ `' V二、需求/ z& t+ z- {7 `: R
       在平常的爬虫开发中,有时候网页是一堆js堆起来的代码,涉及很多异步计算,如果是普通的http 控制台请求,那么得到的源文件是一堆js ,需要自己在去组装数据,很费力;但是采用Selenium+ChromeDriver可以达到所见即所得的完美效果。
: \7 t# C# b1 x* f5 f2 y三、实现方式/ @  A  h) _2 g! z" D+ A, Y
       项目结构:为了方便使用,用的winform程序,附nuget包' ~7 {; u! Y6 X* x
1.jpg 5 H2 ?# G: Y+ {9 O) {5 [/ H
       以下是form1.cs的代码,这里就只放关键方法代码了。需要安装最新的chrome浏览器+代码中使用的chromedriver是 v2.9.248315; W4 p- w" e! ^! Y
  1.     private void crawlingWebFunc()
  2.         {
  3.             SetText("\r\n开始尝试...");
  4.             List<testfold> surls = new List<testfold>();
  5.             string path = System.Environment.CurrentDirectory + "\\图片url\";
  6.             DirectoryInfo root = new DirectoryInfo(path);
  7.             DirectoryInfo[] dics = root.GetDirectories();
  8.             foreach (var itemdic in dics)
  9.             {
  10.                 string txt = "";
  11.                 StreamReader sr = new StreamReader(itemdic.FullName + "\\data.txt");
  12.                 while (!sr.EndOfStream)
  13.                 {
  14.                     string str = sr.ReadLine();
  15.                     txt += str;// + "\n";
  16.                 }
  17.                 sr.Close();
  18.                 surls.Add(new testfold() { key = itemdic.FullName, picurl = txt });
  19.             }
  20.             ChromeDriverService service = ChromeDriverService.CreateDefaultService(System.Environment.CurrentDirectory);
  21.             //  service.HideCommandPromptWindow = true;
  22.             ChromeOptions options = new ChromeOptions();
  23.             options.AddArguments("--test-type", "--ignore-certificate-errors");
  24.             options.AddArgument("enable-automation");
  25.             //   options.AddArgument("headless");
  26.             //  options.AddArguments("--proxy-server=http://user:password@yourProxyServer.com:8080");
  27.             using (IWebDriver driver = new OpenQA.Selenium.Chrome.ChromeDriver(service, options, TimeSpan.FromSeconds(120)))
  28.             {
  29.                 driver.Url = "https://www.1688.com/";
  30.                 Thread.Sleep(200);
  31.                 try
  32.                 {
  33.                     int a = 1;
  34.                     foreach (var itemsurls in surls)
  35.                     {
  36.                         SetText("\r\n第" + a.ToString() + "个");
  37.                         driver.Navigate().GoToUrl(itemsurls.picurl);
  38.                         //登录
  39.                         if (driver.Url.Contains("login.1688.com"))
  40.                         {
  41.                             SetText("\r\n需要登录,开始尝试...");
  42.                             trylogin(driver); //尝试登录完成
  43.                                               //再试试
  44.                             driver.Navigate().GoToUrl("https://s.1688.com/youyuan/index.htm?tab=imageSearch&imageType=oss&imageAddress=cbuimgsearch/eWXC7XHHPN1607529600000&spm=");
  45.                             if (driver.Url.Contains("login.1688.com"))
  46.                             {
  47.                                 //没办法退出
  48.                                 SetText("\r\n退出,换ip重试...");
  49.                                 return;
  50.                             }
  51.                         }
  52.                         //鼠标放上去的内容因为页面自带只能显示一个的原因 没办法做到全部显示 然后在下载 只能是其他方式下载
  53.                         //  var elements = document.getElementsByClassName('hover-container');
  54.                         //  Array.prototype.forEach.call(elements, function(element) {
  55.                         //  element.style.display = "block";
  56.                         //   console.log(element);
  57.                         //  });
  58.                         //   IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
  59.                         //    var sss = js.ExecuteScript(" var elements = document.getElementsByClassName('hover-container');  Array.prototype.forEach.call(elements, function(element) {  console.log(element); element.setAttribute("class", "测试title");  element.style.display = "block";  console.log(element); });");
  60.                         Thread.Sleep(500);
  61.                         var responseModel = Write(itemsurls.key, driver.PageSource, Pagetypeenum.列表);
  62.                         Thread.Sleep(500);
  63.                         int i = 1;
  64.                         foreach (var offer in responseModel?.data?.offerList ?? new List<OfferItemModel>())
  65.                         {
  66.                             driver.Navigate().GoToUrl(offer.information.detailUrl);
  67.                             string responseDatadetail = driver.PageSource;
  68.                             Write(itemsurls.key, driver.PageSource, Pagetypeenum.详情);
  69.                             SetText("\r\n第" + a.ToString() + "-" + i.ToString() + "个");
  70.                             Thread.Sleep(500);
  71.                             i++;
  72.                         }
  73.                     }
  74.                 }
  75.                 catch (Exception ex)
  76.                 {
  77.                     CloseChromeDriver(driver);
  78.                     throw;
  79.                 }
  80.             }
  81.         }
  1.   #region 异常  退出chromedriver
  2.         [DllImport("user32.dll", EntryPoint = "FindWindow")]
  3.         private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
  4.         [DllImport("user32.dll", EntryPoint = "SendMessage")]
  5.         public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
  6.         public const int SW_HIDE = 0;
  7.         public const int SW_SHOW = 5;
  8.         [DllImport("user32.dll", EntryPoint = "ShowWindow")]
  9.         public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
  10.         /// <summary>
  11.         /// 获取窗口句柄
  12.         /// </summary>
  13.         /// <returns></returns>
  14.         public IntPtr GetWindowHandle()
  15.         {
  16.             string name = (Environment.CurrentDirectory + "\\chromedriver.exe");
  17.             IntPtr hwd = FindWindow(null, name);
  18.             return hwd;
  19.         }
  20.         /// <summary>
  21.         /// 关闭chromedriver窗口
  22.         /// </summary>
  23.         public void CloseWindow()
  24.         {
  25.             try
  26.             {
  27.                 IntPtr hwd = GetWindowHandle();
  28.                 SendMessage(hwd, 0x10, 0, 0);
  29.             }
  30.             catch { }
  31.         }
  32.         /// <summary>
  33.         /// 退出chromedriver
  34.         /// </summary>
  35.         /// <param name="driver"></param>
  36.         public void CloseChromeDriver(IWebDriver driver)
  37.         {
  38.             try
  39.             {
  40.                 driver.Quit();
  41.                 driver.Dispose();
  42.             }
  43.             catch { }
  44.             CloseWindow();
  45.         }
  46.         #endregion 异常  退出chromedriver
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|paopaomj.COM ( 渝ICP备18007172号|渝公网安备50010502503914号 )

GMT+8, 2024-11-21 17:10

Powered by paopaomj X3.5 © 2016-2025 sitemap

快速回复 返回顶部 返回列表