在.NET中使用JQuery 选择器精确提取网页内容
1. 前言
相信很多人做开发时都有过这样的需求:从网页中准确提取所需的内容。思前想后,方法无非是以下几种:(本人经验尚浅,有更好的方法还请大家指点)
1. 使用正则表达式匹配所需元素。(缺点:同类型的元素如果有不同的属性,比如<div class='first'>aaa</div><div class='last'>bbb</div>, 如果想要匹配所有div元素时,将会相当麻烦,而且容易得到不想要的结果,漏掉需要的结果。)
2. 将网页转换成XML文档,使用Linq to XML。(缺点:需要一次转换过程,而且效率不高。)
3. 使用网站提供的WebServices或WebAPI等接口直接获取所需数据。(缺点:需要先获得接口文档,一般都不会匿名提供。)
最近几年前端的兴起,越来越多的人开始认识JQuery这个强大的工具并被其折服,其中很重要的一点就是JQuery 选择器,它的简洁,高效,易学使得前端工程师大大提高了工作效率。细想一下,提取网页内容就是和前端打交道,如果可以用JQuery选择器,那就完美了!!!
2. 理论准备
难道要在.NET下自己去做一个选择器?非也,这可不是我等小辈能做出来的。。。。既然已经有JQuery了,为什么不能直接就用它的选择器呢?
1. .NET获得网页内容
这里可以选择webbrowser控件,其实它就是一个微型IE,IE能做的它都能做。有些人会问为什么不用WebClient直接下载网页内容呢?请看第二点。
2. .NET与JS交互
使用webbrowser控件,不仅可以获得网页内容,更加重要的是它提供了与网页交互的功能。使用内置的Document属性,我们可以往网页中注入所需的JS代码并且执行它。
3. 提取并返回所需内容
在.NET中,我们可以用Docment的InvokeScript函数来执行相应的JS函数并获得返回结果。
既然理论都准备好了,接下来我们就实现它吧。
3. 功能实现
测试网页:http://www.mmeinv.com/ (福利网站哦,不过绝无邪恶内容,请编辑明鉴!)
功能需求:提取所有“福利”!!!!
先上图:


从图上可以看出,“福利”都准确地提取出来了。并且可以只获取所需的属性值。你要做的只是输入短短的15个字符。
下面再看看代码实现:
其中wb就是webbrowser控件,此段主要为了在一些不包括JQuery库的网页中注入JQuery库。
void InjectJQuery()
{
HtmlElement jquery = wb.Document.CreateElement("script");
jquery.SetAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js");
wb.Document.Body.AppendChild(jquery);
JQueryInjected = true;
}
这里是注入需要执行的JS函数,因为不同的需求有不同的代码,所以不能重复注入,需求改变时只需要更改已注入的函数即可以。
JQScript = wb.Document.GetElementById("JQScript");
if (JQScript == null)
{
JQScript = wb.Document.CreateElement("script");
JQScript.SetAttribute("id", "JQScript");
JQScript.SetAttribute("type", "text/javascript");
wb.Document.Body.AppendChild(JQScript);
}
这里是关键代码, 根据是否要提取属性而生成不同的代码。注入的代码非常简单,相信懂一点点前端的朋友一看就明白了。而最后的一行代码就是执行注入的函数并获取返回值。
if (txtAttribute.Text.Trim() == string.Empty)
JQScript.SetAttribute("text", "function GetJQValue() { if ($('" + txtSelector.Text + "').length == 1) {" +
"return $('" + txtSelector.Text + "')[0].outerHTML; }" +
" else if ($('" + txtSelector.Text + "').length > 1) {" +
" var allhtml = '';" +
" $('" + txtSelector.Text + "').each(function() {allhtml=allhtml+$(this)[0].outerHTML+'\\r\\n';});" +
" return allhtml;}" +
" else return 'no item found.';}");
else
{
JQScript.SetAttribute("text", "function GetJQValue() { if ($('" + txtSelector.Text + "').length == 1) {" +
"return $('" + txtSelector.Text + "').attr('" + txtAttribute.Text + "'); }" +
" else if ($('" + txtSelector.Text + "').length > 1) {" +
" var allhtml = '';" +
" $('" + txtSelector.Text + "').each(function() {allhtml=allhtml+$(this).attr('" + txtAttribute.Text + "')+'\\r\\n';});" +
" return allhtml;}" +
" else return 'no item found.';}");
}
textBox2.Text = wb.Document.InvokeScript("GetJQValue").ToString();
相信到这里,大家都已经一目了然,短短10几行代码,就可以使用强大的JQuery选择器,效率比以前的旧方法高了不知多少倍,何乐而不为呢?
4. 知识延伸
1. 只要你前端知识够硬,就可以注入更复杂的函数,实现更复杂的内容提取。
2. 在Android和IOS里,理论上也是可以实现这样的功能。
3. 也许有一天,我们会有类似的选择器去代替SQL,实现数据库的高效查询??????????
PS: 小弟文笔极差,知识面不广,如有纰漏,请大家斧正!
PPS:啰嗦也要说了,文章版权本人所有,转载请明确标示并保留原文链接,谢谢大家!
Demo及源代码: http://files.cnblogs.com/XiaoFaye/JQuerySelector.zip
在.NET中使用JQuery 选择器精确提取网页内容的更多相关文章
- 在CodedUI中使用JQuery选择器
在CodedUI中使用JQuery选择器http://automationqa.com/forum.php?mod=viewthread&tid=3574&fromuid=29
- 我人生中的jQuery选择器
Jquery选择器 一.Jquery选择器简介 JavaScript只是一种运行于客户端,可以被客户端浏览器解析的一段代码.它和java没有任何关系.JavaScript简称JS.jQuery是对JS ...
- JQuery选择器大全 前端面试送命题:面试题篇 对IOC和DI的通俗理解 c#中关于协变性和逆变性(又叫抗变)帮助理解
JQuery选择器大全 jQuery 的选择器可谓之强大无比,这里简单地总结一下常用的元素查找方法 $("#myELement") 选择id值等于myElement的元素 ...
- jQuery入门(1)jQuery中万能的选择器
jQuery入门(1)jQuery中万能的选择器 jQuery入门(2)使用jQuery操作元素的属性与样式 jQuery入门(3)事件与事件对象 jQuery入门(4)jQuery中的Ajax()应 ...
- jquery选择器中两个class是什么意思?
jquery选择器中两个class是什么意思? $(".class1 .class2") 选择class1元素下class2的元素(中间有空格)$(".class1.cl ...
- 彻底抛弃PeopleEditor,SharePoint中利用Jquery Chosen创建新的人员选择器
彻底抛弃PeopleEditor,SharePoint中利用Jquery Chosen创建新的人员选择器 基于SharePoint平台开发时,人员选择器使用频率是非常高的,但是原生的人员选择器使用太麻 ...
- jQuery的选择器中的通配符[id^='code']或[name^='code']及jquery选择器总结
1.选择器 (1)通配符: $("input[id^='code']");//id属性以code开始的所有input标签 $("input[id$='code']&quo ...
- 处理jQuery选择器中的特殊符号,如(、#等
前几天解决一个外网问题,客服反馈页面数据加载不出来,首先看一下服务端日志也没报错异常,自己测试了一下,在chrome的Console发现有js报错,原来是js报错导致的数据加载不出来. 调试了一番,发 ...
- jQuery中的:input选择器
jQuery中的:input选择器 jQuery中的:input选择器包含input, textarea, select 和 button这些标签. <!DOCTYPE html> < ...
随机推荐
- android——利用SharedPreference做引导界面
很久以前就接触过sharedPreference这个android中的存储介质.但是一直没有实际使用过,今天在看之前做的“民用机型大全”的app时,突然想到可以使用sharedPreference类来 ...
- sql语句 之聚合函数
聚合分析 在访问数据库时,经常需要对表中的某列数据进行统计分析,如求其最大值.最小值.平均值等.所有这些针对表中一列或者多列数据的分析就称为聚合分析. 在SQL中,可以使用聚合函数快速实现数据的聚 ...
- C++11新特性——初始化列表 initializer_list
破事水: 由于最近数据结构有个实验报告说是要对字符串进行排序,想偷个懒不想一个一个地赋值,虽然可以用strcpy和传入二级指针的形式直接写,但是这样感觉不美观漂亮. 然后就去膜了一下C++11的新特性 ...
- 理解css margin
前提是对display:block元素 1 margin对没有width属性的元素,能影响其宽度,对于有width的则不起作用: 高度方面不受影响 此特性可用来排版 2 margin 与百分比 普通的 ...
- gcc编译命令行依赖库的指定顺序
gcc链接过程中定义了三个集合:可重定位目标文件集合E.未解析符号集合U和已定义符号集合D,链接基本流程如下: 1) 按命令行指定顺序依次处理每个目标文件和库文件: 2) 如果为目标文件,将其加入集合 ...
- 总结-EL表达式
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ tagl ...
- mysql5.1升级到mysql5.6
这么大跨度的升级,本身不推荐.升级应该是循序渐进的,以防止不兼容.如果确实要这么做,你先要确保你的客户端管理工具要能兼容,比如phpmyadmin,此次升级依然存在一个问题,mysql server和 ...
- .NET基于Redis缓存实现单点登录SSO的解决方案[转]
一.基本概念 最近公司的多个业务系统要统一整合使用同一个登录,这就是我们耳熟能详的单点登录,现在就NET基于Redis缓存实现单点登录做一个简单的分享. 单点登录(Single Sign On),简称 ...
- python实现从生成器中取固定角标的元素
#!/usr/bin/env python3 # -*- coding: utf-8 -*- class A: def __init__(self): def r(): i = 1 while Tru ...
- UML序列图总结(Loop、Opt、Par和Alt)
序列图主要用于展示对象之间交互的顺序. 序列图将交互关系表示为一个二维图.纵向是时间轴,时间沿竖线向下延伸.横向轴代表了在协作中各独立对象的类元角色.类元角色用生命线表示.当对象存在时,角色用一条虚线 ...