现在大多数网站都是随着滚动条的滑动加载页面内容的,因此单纯获得静态页面的Html是无法获得全部的页面内容的。使用Selenium就可以模拟浏览器拉动滑动条来加载所有页面内容。

前情提要

Selenium简介

Selenium是一个WEB自动化测试工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。Selenium也是一款同样使用Apache License 2.0协议发布的开源框架。

C#安装Selenium

本文仅仅是使用Selenium实现拉动滚动条的功能,所以不对Selenium进行过多的介绍。

通过Nuget包管理器搜索"Selenium",分别安装:

  • Selenium.WebDriver
  • Selenium.Chrome.WebDriver

实例(获取某网站主页所有图片)

普通获取网页Html

ChromeDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl(url);
string title = driver.Title;//页面title
string html = driver.PageSource;//页面Html

不启动Chrome窗口及关闭Chrome控制台获取网页

程序执行时会自动打开Chrome窗口和输出控制台中一些信息,我们不需要这些东西。

//不启动chrome窗口
ChromeOptions options = new ChromeOptions();
options.AddArgument("headless"); //关闭ChromeDriver控制台
ChromeDriverService driverService = ChromeDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true; ChromeDriver driver = new ChromeDriver(driverService, options);
driver.Navigate().GoToUrl(url);

将页面滚动到底部

如果使用scrollTo(0, document.body.scrollHeight),直接让将页面滚动到底部会导致页面中间部分读取失败,所以需要分几次滑动并且给页面足够的时间加载

for (int i = 1; i <= 10; i++)
{
string jsCode = "window.scrollTo({top: document.body.scrollHeight / 10 * " + i + ", behavior: \"smooth\"});";
//使用IJavaScriptExecutor接口运行js代码
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript(jsCode);
//暂停滚动
Thread.Sleep(1000);
}

使用HtmlAgilityPack解析读取到的Html

以下内容与上一篇文章基本相同

string title = driver.Title;//页面title
string html = driver.PageSource;//页面Html HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(html);//解析Html字符串
string imgPath = "//img";//选择img
//获取img标签中的图片
foreach (HtmlNode node in doc.DocumentNode.SelectNodes(imgPath))
{
······
}

完整代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using HtmlAgilityPack;
using System.Text.RegularExpressions;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Threading; namespace WebCrawlerDemo
{
class Program
{
static void Main(string[] args)
{
WebClient wc = new WebClient(); int imgNum = 0;//图片编号
string url = "https://www.bilibili.com"; string html = FinalHtml.GetFinalHtml(url, 10); HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(html); string imgPath = "//img";//选择img //HtmlNode nodes = hd.DocumentNode.SelectSingleNode(path); //获取img标签中的图片
foreach (HtmlNode node in doc.DocumentNode.SelectNodes(imgPath))
{
if (node.Attributes["src"] != null)
{
string imgUrl = node.Attributes["src"].Value.ToString();
if (imgUrl != "" && imgUrl != " ")
{
imgNum++; //生成文件名,自动获取后缀
string fileName = GetImgName(imgUrl, imgNum); //Console.WriteLine(fileName);
//Console.WriteLine(imgUrl);
ImgDownloader.DownloadImg(wc, imgUrl, "images/", fileName);
}
}
}
//获取背景图
string bgImgPath = "//*[@style]";//选择具有style属性的节点
foreach (HtmlNode node in doc.DocumentNode.SelectNodes(bgImgPath))
{
if (node.Attributes["style"].Value.Contains("background-image:url"))
{
imgNum++;
string bgImgUrl = node.Attributes["style"].Value;
bgImgUrl = Regex.Match(bgImgUrl, @"(?<=\().+?(?=\))").Value;//读取url()的内容
//Console.WriteLine(bgImgUrl);
//生成文件名,自动获取后缀
string fileName = GetImgName(bgImgUrl, imgNum); ImgDownloader.DownloadImg(wc, bgImgUrl, "images/bgcImg/", fileName);
}
}
Console.WriteLine("----------END----------");
Console.WriteLine($"一共获得: {imgNum}张图");
Console.ReadKey();
}
}
/// <summary>
/// 图片下载器
/// </summary>
public class ImgDownloader
{
/// <summary>
/// 下载图片
/// </summary>
/// <param name="webClient"></param>
/// <param name="url">图片url</param>
/// <param name="folderPath">文件夹路径</param>
/// <param name="fileName">图片名</param>
public static void DownloadImg(WebClient webClient, string url, string folderPath, string fileName)
{
//如果文件夹不存在,则创建一个
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
//判断路径是否完整,补全不完整的路径
if (url.IndexOf("https:") == -1 && url.IndexOf("http:") == -1)
{
url = "https:" + url;
}
//下载图片
try
{
webClient.DownloadFile(url, folderPath + fileName);
Console.WriteLine(fileName + "下载成功");
}
catch (Exception ex)
{
Console.Write(ex.Message);
Console.WriteLine(url);
}
}
/// <summary>
/// 生成图片名称
/// </summary>
/// <param name="imageUrl">图片地址</param>
/// <param name="imageNum">图片编号</param>
/// <returns></returns>
public static string GetImgName(string imageUrl, int imageNum)
{
string imgExtension;
if (imageUrl.LastIndexOf(".") != -1)
{
imgExtension = imageUrl.Substring(imageUrl.LastIndexOf("."));
}
else
{
imgExtension = ".jpg";
}
return imageNum + imgExtension;
}
}
/// <summary>
/// 获得执行过js的网址
/// </summary>
public class FinalHtml
{
/// <summary>
/// 获得拉动滚动条后的页面
/// </summary>
/// <param name="url">网址</param>
/// <param name="sectionNum">滚动几次</param>
/// <returns>html字符串</returns>
public static string GetFinalHtml(string url, int sectionNum)
{
//不启动chrome窗口
ChromeOptions options = new ChromeOptions();
options.AddArgument("headless"); //关闭ChromeDriver控制台
ChromeDriverService driverService = ChromeDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true; ChromeDriver driver = new ChromeDriver(driverService, options); driver.Navigate().GoToUrl(url); string title = driver.Title;
Console.WriteLine($"Title: {title}");
//将页面滚动到底部
Console.Write("页面滚动中,请稍后"); for (int i = 1; i <= sectionNum; i++)
{
string jsCode = "window.scrollTo({top: document.body.scrollHeight / " + sectionNum + " * " + i + ", behavior: \"smooth\"});";
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript(jsCode);
Console.Write(".");
Thread.Sleep(1000);
}
Console.WriteLine(); string html = driver.PageSource;
driver.Quit(); return html;
}
}
}

参考文章

C# HtmlAgilityPack+Selenium爬取需要拉动滚动条的页面内容的更多相关文章

  1. HtmlUnit爬取Ajax动态生成的页面内容

    HtmlUnit说白了就是一个浏览器,这个浏览器是用Java写的无界面的浏览器,正因为其没有界面,因此执行的速度还是可以滴. HtmlUnit提供了一系列的API,这些API可以干的功能比较多,如表单 ...

  2. selenium模块使用详解、打码平台使用、xpath使用、使用selenium爬取京东商品信息、scrapy框架介绍与安装

    今日内容概要 selenium的使用 打码平台使用 xpath使用 爬取京东商品信息 scrapy 介绍和安装 内容详细 1.selenium模块的使用 # 之前咱们学requests,可以发送htt ...

  3. [Python爬虫] Selenium爬取新浪微博客户端用户信息、热点话题及评论 (上)

    转载自:http://blog.csdn.net/eastmount/article/details/51231852 一. 文章介绍 源码下载地址:http://download.csdn.net/ ...

  4. selenium爬取煎蛋网

    selenium爬取煎蛋网 直接上代码 from selenium import webdriver from selenium.webdriver.support.ui import WebDriv ...

  5. 利用selenium爬取京东商品信息存放到mongodb

    利用selenium爬取京东商城的商品信息思路: 1.首先进入京东的搜索页面,分析搜索页面信息可以得到路由结构 2.根据页面信息可以看到京东在搜索页面使用了懒加载,所以为了解决这个问题,使用递归.等待 ...

  6. 利用Selenium爬取淘宝商品信息

    一.  Selenium和PhantomJS介绍 Selenium是一个用于Web应用程序测试的工具,Selenium直接运行在浏览器中,就像真正的用户在操作一样.由于这个性质,Selenium也是一 ...

  7. Scrapy 框架 使用 selenium 爬取动态加载内容

    使用 selenium 爬取动态加载内容 开启中间件 DOWNLOADER_MIDDLEWARES = { 'wangyiPro.middlewares.WangyiproDownloaderMidd ...

  8. 使用selenium爬取网站动态数据

    处理页面动态加载的爬取 selenium selenium是python的一个第三方库,可以实现让浏览器完成自动化的操作,比如说点击按钮拖动滚轮等 环境搭建: 安装:pip install selen ...

  9. scrapy框架 + selenium 爬取豆瓣电影top250......

    废话不说,直接上代码..... 目录结构 items.py import scrapy class DoubanCrawlerItem(scrapy.Item): # 电影名称 movieName = ...

随机推荐

  1. uni-app 模拟器

    1.安装MuMu模拟器 Android模拟器端口: 7555 2.安装夜神模拟器 Android模拟器端口: 62001

  2. xmind 破解

    邮箱:x@iroader 序列号: XAka34A2rVRYJ4XBIU35UZMUEEF64CMMIYZCK2FZZUQNODEKUHGJLFMSLIQMQUCUBXRENLK6NZL37JXP4P ...

  3. hdoj - 2602 Bone Collector

    Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bone Collec ...

  4. Oracle复习思路

    目录 Oracle复习 题型 复习大纲 附录 SQL题目一 SQL题目二 SQL题目三 SQL题目四 SQL题目五 SQL题目六 Oracle复习 题型 选择题15题 每题2分,共30分 判断题10题 ...

  5. AOP注解方式ApsectJ开发

    AOP注解方式ApsectJ开发 引入配置文件 编写切面类配置 使用注解的AOP对象目标类进行增强 在配置文件中开启以注解形式进行AOP开发 在切面类上添加注解 注解AOP通知类型 @Before前置 ...

  6. NoSql数据库Redis系列(5)——Redis主从复制

    前面介绍Redis,我们都在一台服务器上进行操作的,也就是说读和写以及备份操作都是在一台Redis服务器上进行的,那么随着项目访问量的增加,对Redis服务器的操作也越加频繁,虽然Redis读写速度都 ...

  7. 请简述web开发中的兼容问题

    1,浏览器默认的内外边距不一样,所以用通用选择器*设置margin和padding来设置.2,块标签设置浮动后,有设置margin的情况下,在ie6下的margin比别的浏览器大.3,img标签会有默 ...

  8. c++ 字符串时间格式转换为时间 判断有效期

    转载:https://www.cnblogs.com/maphc/p/3462952.html #include <iostream> #include <time.h> us ...

  9. USB安装ESXi出错,menu.c32 not a com32r image

    USB安装EXSi出错,menu.c32 not a com32r image 不能进入安装界面. 提供提取的menu.c32 下载下来覆盖U盘根目录源文件 EXSi6.7测试可以用 文件csdn下载 ...

  10. Ubuntu安装FreeSWITCH亲测

    本人在安装FreeSWITCH的时候遇到了相当多的坑,网上很多方法都模棱两可,经常装失败,最后终于装成功后做一下总结 最顺利的安装方式 1. 下载压缩文件 下载地址:http://files.free ...