c# http请求ajax页面
我们在用Http请求的时候,某些页面是ajax加载的,所以请求过来的页面数据不完整。也就是说ajax局部加载数据的地方,我们请求不到,这时候该怎么办呢?
WebDriver+phantomjs 这两个组合在一起使用,可以完成此任务。分别简单介绍下,WebDriver是一个前端的自动化测试框架,phantomjs是一个无界面的浏览器,基于webkit。WebDriver调用phantomjs.exe工作。下面是WebDriver提供的API,看来它能驱动各种浏览器工作。
使用前准备:
在Nuget上,下载 Selenium.WebDriver和Selenium.PhantomJS.WebDriver两个包,在项目中引用 WebDriver.dll,在输出目录下要有phantomjs.exe。
我们看一个完整的例子:
- using OpenQA.Selenium;
- using OpenQA.Selenium.PhantomJS;
- using OpenQA.Selenium.Support.UI;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- namespace ConsoleApplication1
- {
- public interface ICrawler
- {
- event EventHandler<OnStartEventArgs> OnStart;
- event EventHandler<OnCompletedEvent> OnCompleted;
- event EventHandler<OnErrorEventArgs> OnError;
- Task Start(Uri uri, Script script, Operation opreation);
- }
- public class Operation
- {
- public Action<PhantomJSDriver> Action;
- public Func<IWebDriver, bool> Condition;
- public int timeout { get; set; }
- }
- public class Script
- {
- public string Code { set; get; }
- public object[] Args { set; get; }
- }
- public class OnStartEventArgs
- {
- public Uri Uri { set; get; }
- public OnStartEventArgs(Uri uri)
- {
- this.Uri = uri;
- }
- }
- public class OnErrorEventArgs
- {
- public Uri Uri { set; get; }
- public Exception Exception { set; get; }
- public OnErrorEventArgs(Uri uri, Exception ex)
- {
- this.Uri = uri;
- this.Exception = ex;
- }
- }
- public class OnCompletedEvent
- {
- public Uri Uri { set; get; }
- public int ThreadId { set; get; }
- public string PageSource { get; private set; }
- public long Milliseconds { get; private set; }
- public PhantomJSDriver Driver { get; private set; }
- public OnCompletedEvent(Uri uri, int threadId, string pageSource, long milliseconds, PhantomJSDriver driver)
- {
- this.Uri = uri;
- this.ThreadId = threadId;
- this.PageSource = pageSource;
- this.Milliseconds = milliseconds;
- this.Driver = driver;
- }
- }
- public class HighCrawler : ICrawler
- {
- public event EventHandler<OnStartEventArgs> OnStart;
- public event EventHandler<OnCompletedEvent> OnCompleted;
- public event EventHandler<OnErrorEventArgs> OnError;
- private static PhantomJSOptions _options;
- private static PhantomJSDriverService _service;
- static HighCrawler()
- {
- var service = PhantomJSDriverService.CreateDefaultService();
- service.DiskCache = true;
- service.IgnoreSslErrors = true;
- service.HideCommandPromptWindow = true;
- service.LoadImages = false;
- service.LocalToRemoteUrlAccess = true;
- _service = service;
- _options = new PhantomJSOptions();
- }
- public Task Start(Uri uri, Script script, Operation operation)
- {
- return Task.Factory.StartNew(() =>
- {
- if (OnStart != null)
- {
- this.OnStart(this, new OnStartEventArgs(uri));
- }
- var driver = new PhantomJSDriver(_service, _options);
- try
- {
- var watch = DateTime.Now;
- driver.Navigate().GoToUrl(uri.ToString());
- if (script != null)
- driver.ExecuteScript(script.Code, script.Args);
- if (operation.Action != null) operation.Action.Invoke(driver);
- var driverWait = new WebDriverWait(driver, TimeSpan.FromMilliseconds(operation.timeout)); //设置超时时间
- if (operation.Condition != null) driverWait.Until(operation.Condition);
- var threadId = Thread.CurrentThread.ManagedThreadId;
- var milliseconds = DateTime.Now.Subtract(watch).Milliseconds;
- var pageSource = driver.PageSource;
- if (this.OnCompleted != null)
- this.OnCompleted(this, new OnCompletedEvent(uri, threadId, pageSource, milliseconds, driver));
- }
- catch (Exception ex)
- {
- if (OnError != null)
- this.OnError(this, new OnErrorEventArgs(uri, ex));
- }
- finally
- {
- driver.Close();
- driver.Quit();
- }
- });
- }
- }
- }
这是封装了一个类,方便使用,我们看如何使用:
- /// <summary>
- /// 解析网站
- /// </summary>
- /// <param name="url">待解析的网站</param>
- /// <param name="waitId">等待加载的元素Id:"search-main"</param>
- /// <param name="xpath">解析路径:"//div[@class=\"article panel article-result\"]//h5[@class=\"title\"]//a"</param>
- private static void TestWaitForReady(string url, string waitId, string xpath, int timeout = )
- {
- var crawler = new HighCrawler();
- crawler.OnStart += (s, e) =>
- {
- Console.WriteLine("爬虫开始抓取地址:" + e.Uri.ToString());
- };
- crawler.OnError += (s, e) =>
- {
- Console.WriteLine("爬虫出现错误:" + e.Uri.ToString() + ",异常信息" + e.Exception.ToString());
- };
- crawler.OnCompleted += (s, e) =>
- {
- Console.WriteLine("接收到的源码长度:" + e.PageSource.Length);
- Thread.Sleep();
- Console.WriteLine("爬虫结束,花费时间:" + e.Milliseconds);
- var items = e.Driver.FindElements(By.XPath(xpath));
- foreach (var item in items)
- {
- Console.WriteLine(item.Text);
- }
- };
- var operition = new Operation
- {
- Action = (x) =>
- {
- },
- Condition = (x) =>
- {
- return x.FindElement(By.Id(waitId)).Displayed;
- },
- timeout = timeout
- };
- crawler.Start(new Uri(url), null, operition);
- }
取ajax异步结果的核心原理:WebDriver把页面上的某个元素,作为标识,一旦出现此元素,表明ajax结束,这时候再返回结果,中间有个等待的过程。
c# http请求ajax页面的更多相关文章
- C# 动态创建SQL数据库(二) 在.net core web项目中生成二维码 后台Post/Get 请求接口 方式 WebForm 页面ajax 请求后台页面 方法 实现输入框小数多 自动进位展示,编辑时实际值不变 快速掌握Gif动态图实现代码 C#处理和对接HTTP接口请求
C# 动态创建SQL数据库(二) 使用Entity Framework 创建数据库与表 前面文章有说到使用SQL语句动态创建数据库与数据表,这次直接使用Entriy Framwork 的ORM对象关 ...
- ajax 多个setInterval进行ajax请求的页面长时间打开会出现页面卡死问题
多个setInterval进行ajax请求的页面长时间打开会出现页面卡死问题 浏览器的渲染(UI)线程和js线程是互斥的,在执行js耗时操作时,页面渲染会被阻塞掉.当我们执行异步ajax的时候没有问 ...
- Egret和Http请求 (Ajax、XMLHttpRequest、Post、Get)
一 Http请求 二 AJax和XMLHttpRequest 三 一个Ajax例子 四 Egret中的egret.HttpRequest 五 Post和Get区别 一 Http请求 Http深入 ...
- Learning Scrapy笔记(六)- Scrapy处理JSON API和AJAX页面
摘要:介绍了使用Scrapy处理JSON API和AJAX页面的方法 有时候,你会发现你要爬取的页面并不存在HTML源码,譬如,在浏览器打开http://localhost:9312/static/, ...
- 使用服务器端控制AJAX页面缓存
你知道 response.setHeader("Cache-Control","no-cache"); 这条语句是干什么的吗? 这是用来防止浏览器缓存动态内容生 ...
- JavaScrpit中异步请求Ajax实现
在前端页面开发的过程中,经常使用到Ajax请求,异步提交表单数据,或者异步刷新页面. 一般来说,使用Jquery中的$.ajax,$.post,$.getJSON,非常方便,但是有的时候,我们只因为需 ...
- 异步请求Ajax(取得json数据)
异步请求Ajax 没有学习Ajax之前请求数据的时候都是整个页面全部刷新了一次,也就是每次请求都会重新请求所有的资源.但是在很多时候不需要页面全部刷新,仅仅是需要页面的局部数据刷新即可,此时需要发送异 ...
- ajax 页面无刷新
<!-- 使用原生Ajax 和 $.ajax 实现局部刷新的过程 --><!-- 封装通用XMLHttpRequest对象 --><!DOCTYPE html>&l ...
- HTTP 错误 404.3 – Not Found 由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。如果应下载文件,请添加 MIME 映射。
今天,在vs2013中新建了一个placard.json文件,当我用jq读取它的时候,去提示404,直接在浏览器访问这个文件,提示: HTTP 错误 404.3 – Not Found 由于扩展配置问 ...
随机推荐
- Linux系统编程---实现目录或者文件拷贝
关于拷贝文件,前面写过一个例子:点击打开链接 ,可以看看,实现cp命令. 这次我们实现一个目录和文件的拷贝,综合点. #include <stdio.h> #include <fcn ...
- 程序员必须搞清的概念-equals和=和hashcode的区别
1. 首先equals()和hashcode的介绍 equals 方法在非空对象引用上实现相等关系: * 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true. * 对称性:对于 ...
- 剑指Offer--排序算法小结
剑指Offer--排序算法小结 前言 毕业季转眼即到,工作成为毕业季的头等大事,必须得认认真真进行知识储备,迎战笔试.电面.面试. 许久未接触排序算法了.平时偶尔接触到时自己会不假思索的百度,然后就是 ...
- Android实现横屏以及全屏的小技巧
分享两个安卓的实用小技巧,那就是横屏和全屏的实现. 首先是横屏的实现 首先是在清单文件中实现 <activity android:name=".MainActivity" a ...
- Docker教程:使用docker配置python开发环境
http://blog.csdn.net/pipisorry/article/details/50808034 Docker的安装和配置 [Docker教程:docker的安装] [Docker教程: ...
- HMM:隐马尔科夫模型-维特比算法
http://blog.csdn.net/pipisorry/article/details/50731584 目标-解决HMM的基本问题之二:给定观察序列O=O1,O2,-OT以及模型λ,如何选择一 ...
- ROS_Kinetic_01 在ubuntu 16.04安装ROS Kinetic 2017.01更新
ROS_Kinetic系列学习(一),在ubuntu 16.04安装ROS Kinetic. Celebrating 9 Years of ROS! ubuntu16.04已经发布半年多了,ROS的K ...
- 【Unity Shaders】Reflecting Your World —— 在Unity3D中创建Cubemaps
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- [Django高级]理解django中的中间件机制和执行顺序
原文来自 Understanding Django Middlewares, 这篇文章从整体上介绍了django中中间件定义,作用,和怎么样自己写中间件 –orangleliu. 注:middlewa ...
- UILTView经典知识点练习
作者:韩俊强 未经允许,请勿转载! 关注博主:http://weibo.com/hanjunqiang 声明:UILTView 指:UILabel 和 UITextField 的复合 #impor ...