c#爬取Silverlight网页[通俗易懂]

c#爬取Silverlight网页[通俗易懂]前言:爬取普通的文本网页非常容易,但爬取Silverlight的网页代码时,有时候可能会加密。这样就会很麻烦了。下面就爬取网站http://zx.bjmemc.com.cn/(北京空气质量网)进行说明。任务:网站http://zx.bjmemc.com.cn/显示的内容如下图所示。我们的任务就是将空气质量数据抓取下来。工具:1、fiddler,http://www.

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

前言:

爬取普通的文本网页非常容易,但爬取Silverlight的网页代码时,有时候可能会加密。这样就会很麻烦了。下面就爬取网站http://zx.bjmemc.com.cn/ (北京空气质量网)进行说明。

任务:

网站http://zx.bjmemc.com.cn/显示的内容如下图所示。我们的任务就是将空气质量数据抓取下来。

c#爬取Silverlight网页[通俗易懂]

工具:

1、fiddler,http://www.telerik.com/fiddler,一款优秀的网页请求分析工具

2、reflector,http://download.csdn.net/detail/qing_lgq/6764265,.net源码激活成功教程工具

步骤

1、安装fiddler和reflector,并激活成功教程reflector。注意,下载、安装和激活成功教程reflector的时候请关闭杀毒软件,内有注册机,可能会被杀毒软件直接删除。

2、打开fiddler,使之处于监听状态。

3、用浏览器打开网页:http://zx.bjmemc.com.cn/。(此网站做得非常好,为了防止爬取,一旦用户打开浏览器自带的developer tool,就不会加载任何东西,为他们点个赞,这就是为什么我们必须用fiddler等分析工具的原因)

4、待网页加载完毕,fiddler便已经抓取到了所有的网页请求,如下图所示。在此简要说明一下fiddler的页面布局。左侧是所有的网页请求,右上是发送请求信息,右下是对应的接收信息。最下边状态栏的左边有两个按钮,左侧的是监听开关(下图是关闭状态,未显示该按钮),右侧的ie图标是监听对象,可以选择监听网页请求、非网页请求还是所有进程的请求。注意请求信息和接收信息窗口都有很多tag,根据自己的需求切换。

c#爬取Silverlight网页[通俗易懂]

5、在fiddler左侧找到网页的直接请求,即上图的左侧的第二项,返回信息窗口的tag切换到textview。在窗口的搜索框输入xap,快速找到<param name=”source” value=”ClientBin/BEPB.xap”/>,其中的value属性值就是后台Silverlight的代码。

6、将ClientBin/BEPB.xap与当前网页网址拼接为http://zx.bjmemc.com.cn/ClientBin/BEPB.xap,用浏览器打开,浏览器自动下载BEPB.xap文件。

7、修改BEPB.xap文件名后缀为BEPB.zip,用压缩文件解压缩,得到的文件夹内容如下图所示。这些就是Silverlight后台文件以及引用文件。其中BEPB.dll是该Silverlight项目的核心文件。

c#爬取Silverlight网页[通俗易懂]

8、用reflector打开BEPB.dll,如下图所示。左侧是方法名/命名空间名,右侧是对应的代码。接下来便是一个痛苦的过程了,得一个一个分析,找到密钥。但是还是有章可循。

c#爬取Silverlight网页[通俗易懂]

9、fiddler继续上场。如下图所示。经过分析,获得空气质量数据的是第7个请求,选中它,右下部分的返回信息窗口的tag选择HexView,表示以十六进制显示。右上部分发送信息窗口选择Raw,可是发送时post的数据调用了DataService下的GetWebData方法,在reflector的搜索框中输入此两个关键字,如此顺藤摸瓜,便能很快找到加密的密码。

c#爬取Silverlight网页[通俗易懂]

10、上图右下返回信息窗口的hexview中,两端有部分信息并不是加密信息,分析需要将返回信息的两端无用字节删除。

以下附上Silverlight加解密的代码。具体抓取代码便不公布了,具体情况具体分析,这里只是提供一个大体思路。

/// <summary>
/// hmacSha1算法加密(生成长度40)
/// </summary>
/// <param name="signatureString">加密明文</param>
/// <param name="secretKey">加密密钥</param>
/// <param name="raw_output">是否输出原始编码</param>
/// <returns></returns>
public static object hmacSha1(string signatureString, string secretKey, bool raw_output = false)
{
	var enc = Encoding.UTF8;
	HMACSHA1 hmac = new HMACSHA1(enc.GetBytes(secretKey));
	hmac.Initialize();

	byte[] buffer = enc.GetBytes(signatureString);
	if (raw_output)
	{
		return hmac.ComputeHash(buffer);
	}
	else
	{
		return BitConverter.ToString(hmac.ComputeHash(buffer)).Replace("-", "").ToLower();
	}
}

/// <summary>
/// 使用AES加密字符串
/// </summary>
/// <param name="encryptString">待加密字符串</param>
/// <param name="encryptKey">加密密匙</param>
/// <param name="salt">盐</param>
/// <returns>加密结果,加密失败则返回源串</returns>
public static string EncryptAES(string encryptString, string encryptKey, string salt)
{
	AesManaged aes = null;
	MemoryStream ms = null;
	CryptoStream cs = null;

	string str = null;

	try
	{
		Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(encryptKey, Encoding.UTF8.GetBytes(salt));

		aes = new AesManaged();
		aes.Key = rfc2898.GetBytes(aes.KeySize / 8);
		aes.IV = rfc2898.GetBytes(aes.BlockSize / 8);

		ms = new MemoryStream();
		cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write);

		byte[] data = Encoding.UTF8.GetBytes(encryptString);
		cs.Write(data, 0, data.Length);
		cs.FlushFinalBlock();

		str = Convert.ToBase64String(ms.ToArray());
	}
	catch
	{
		str = encryptString;
	}
	finally
	{
		if (cs != null)
			cs.Close();

		if (ms != null)
			ms.Close();

		if (aes != null)
			aes.Clear();
	}

	return str;
}

/// <summary>
/// 使用AES解密字符串
/// </summary>
/// <param name="decryptString">待解密字符串</param>
/// <param name="decryptKey">解密密匙</param>
/// <param name="salt">盐</param>
/// <returns>解密结果,解谜失败则返回源串</returns>
public static string DecryptAES(string decryptString, string decryptKey, string salt)
{
	AesManaged aes = null;
	MemoryStream ms = null;
	CryptoStream cs = null;

	string str = null;

	try
	{
		Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(decryptKey, Encoding.UTF8.GetBytes(salt));

		aes = new AesManaged();
		aes.Key = rfc2898.GetBytes(aes.KeySize / 8);
		aes.IV = rfc2898.GetBytes(aes.BlockSize / 8);

		ms = new MemoryStream();
		cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write);

		byte[] data = Convert.FromBase64String(decryptString);
		cs.Write(data, 0, data.Length);
		cs.FlushFinalBlock();

		str = Encoding.UTF8.GetString(ms.ToArray(), 0, ms.ToArray().Length);
	}
	catch
	{
		str = decryptString;
	}
	finally
	{
		if (cs != null)
			cs.Close();

		if (ms != null)
			ms.Close();

		if (aes != null)
			aes.Clear();
	}

	return str;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/180413.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm 换行_pycharm自动换行快捷键

    pycharm 换行_pycharm自动换行快捷键python脚本有时一行代码写的非常长,一个屏幕塞不下,左右拉动滚动条视觉不友好。第一种方法:python里有换行标识”\”,如jfdb=spark.read.format(“jdbc”).option(“driver”,mysql_driver).option(“url”,mysql_url).option(“dbtable”,”xxxxxxxxxxxxxxxxxxxxxxxx”).option(“user”,mysql_acount).option(“password”,mysql_pa

    2022年8月28日
    3
  • echart横坐标字体样式问题 xAxis属性问题

    echart横坐标字体样式问题 xAxis属性问题

    2020年11月9日
    262
  • 闫学灿acwing_二叉树外部路径内部路径

    闫学灿acwing_二叉树外部路径内部路径Ural 大学有 N 名职员,编号为 1∼N。他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。每个职员有一个快乐指数,用整数 Hi 给出,其中 1≤i≤N。现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。输入格式第一行一个整数 N。接下来 N 行,第 i 行表示 i 号职员的快乐指数 Hi。接下来 N−1 行,每行输入一对整数 L,K,表示 K 是 L 的直接

    2022年8月9日
    10
  • 循环队列的元素个数计算公式是什么_队列求元素个数

    循环队列的元素个数计算公式是什么_队列求元素个数因为循环对列,rear不一定比front大如果rear<front结果是rear-front+maxsize如果rear>front结果是rear-front为了用一个表达式同时表达两者,用(rear-front+maxsize)%maxsize假设maxsize=10rear=1front=9,那么结果是2rear=9front=1,那么结果是8…

    2025年7月18日
    3
  • 必读,sql加索引调优案例和explain extended说明

    做一个积极的人编码、改bug、提升自己我有一个乐园,面向编程,春暖花开!昨天分享了Mysql中的 explain 命令,使用 explain 来分析 select 语句的运行效果,如 :explain可以获得select语句使用的索引情况、排序的情况等等。链接:顺便提到了explain extended,有小伙伴留言说想知道一些explain extended,那今天就在简单讲解一下。…

    2022年2月28日
    35
  • 数据仓库ods层设计_数据仓库建模的流程有几个

    数据仓库ods层设计_数据仓库建模的流程有几个当我们的数据采集到hdfs层上之后,我们就开开始对数据进行建模以便后来分析,那么我们整体的架构先放在每个建模层级的最前面所以项目1的将行为数据和业务数据导入到hdfs中我们已经完成了,现在需要的是将hdfs的数据通过ODS层数据建模,初步的分析以及改变,那么我们首先介绍下ODS层的作用因为我们的数据刚落到hdfs上,他还只是单纯的数据,并没有能让我们直接操作。所以我们需要将这些数据放入到能够对数据进行操作的框架中,如我们这个项目采取了使用hive的方法。所以我们此次在ODS层需要做到的就是将hdfs

    2022年9月1日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号