Code Bye

网站爬虫问题

http://www.pbc.gov.cn/publish/zhengcehuobisi/637/index.html
想从此网站中选取当日连接,然后获取汇率数据,结果最近不知道发什么神经,给搞了js加密,用webclient跟webrequest均失败,js加密破解一层后也还是不会获取真实地址,没办法,技术不到家,求各种高人帮忙啊~

哪里有加密? 哪里有js? 你想获取当日的还不简单, 解析html源, 得到style=”height:920px”后面的第一个链接。 
<a\s+href="([^"]*)"[^<>]*?class="newslist_style".*?>

用上面的正则抓浏览结果

引用 2 楼 starfd 的回复:
<a\s+href="([^"]*)"[^<>]*?class="newslist_style".*?>

用上面的正则抓浏览结果

$1是url部分

引用 1 楼 jackrebel 的回复:

哪里有加密? 哪里有js? 你想获取当日的还不简单, 解析html源, 得到style=”height:920px”后面的第一个链接。 

<html>
<head>
</head>
<body>
<noscript>
<h1><strong>请开启JavaScript并刷新该页.</strong></h1>
</noscript>
<script type="text/javascript">
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"""":e(parseInt(c/a)))+((c=c%a)>32?String.fromCharCode(c+32):c.toString(33))};if(!"""".replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return""\w+""};c=1};while(c--)if(k[c])p=p.replace(new RegExp(""\b""+e(c)+""\b"",""g""),k[c]);return p}(""14 C="j";14 19="h";14 1a="k";14 10=c;14 E = "d+/=";I f(Z) {14 T, M, Q;14 n, o, p;Q = Z.R;M = 0;T = "";16 (M < Q) {n = Z.r(M++) & 6;N (M == Q) {T += E.q(n >> a);T += E.q((n & 1) << b);T += "==";m;}o = Z.r(M++);N (M == Q) {T += E.q(n >> a);T += E.q(((n & 1) << b) | ((o & 5) >> b));T += E.q((o & 4) << a);T += "=";m;}p = Z.r(M++);T += E.q(n >> a);T += E.q(((n & 1) << b) | ((o & 5) >> b));T += E.q(((o & 4) << a) | ((p & 3) >> c));T += E.q(p & 2);}V T;}I G(){14 15= 18.P||A.B.t||A.l.t;14 J= 18.O||A.B.s||A.l.s;N (15*J <= 8) {V 13;}14 1c = 18.X;14 1d = 18.Y;N (1c + 15 <= 0 || 1d + J <= 0 || 1c >= 18.W.17 || 1d >= 18.W.L) {V 13;}V F;}I g(){14 11 = 19+1a;14 K = 0;14 M    = 0;H(M = 0; M < 11.R; M++) {K += 11.r(M);}K *= 9;K += 7;V "i"+K;}I e(){N(G()) {} D {14 w = "";	w = "1b="+f(10.12()) + "; U=/";A.v = w;	14 u = g();w = "19="+f(u.12()) + "; U=/";A.v = w;	18.S=C;}}e();"",59,73,""0|0x3|0x3f|0xc0|0xf|0xf0|0xff|111111|120000|17|2|4|6|ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789|HXXTTKKLLPPP5|KTKY2RBD9NHPBCIHV9ZMEQQDARSLVFDU|QWERTASDFGXYSF|RANDOMSTR8919|WZWS_CONFIRM_PREFIX_LABEL6|/publish/zhengcehuobisi/637/index.html|STRRANDOM8919|body|break|c1|c2|c3|charAt|charCodeAt|clientHeight|clientWidth|confirm|cookie|cookieString|document|documentElement|dynamicurl|else|encoderchars|false|findDimensions|for|function|h|hash|height|i|if|innerHeight|innerWidth|len|length|location|out|path|return|screen|screenX|screenY|str|template|tmp|toString|true|var|w|while|width|window|wzwschallenge|wzwschallengex|wzwstemplate|x|y"".split(""|""),0,{}))
</script>
</body>
</html>

webclient取出来的是这个啊

引用 3 楼 starfd 的回复:
Quote: 引用 2 楼 starfd 的回复:
<a\s+href="([^"]*)"[^<>]*?class="newslist_style".*?>

用上面的正则抓浏览结果

$1是url部分

能获取源码的话,我也能取到的,大不了麻烦点,但是问题就是解析源码得到的是用js的eval()函数加密地址的东西。。。

这不是加密,这是整个页面通过js加载显示的
http://www.daxueit.com/article/2270.html
试试NHtmlUnit
引用 7 楼 starfd 的回复:

http://www.daxueit.com/article/2270.html
试试NHtmlUnit

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHtmlUnit;
using System.Threading;
using NHtmlUnit.Html;


namespace Consoletest
{
    class Program
    {
        static void Main(string[] args)
        {
            WebClient client = new WebClient();
            client.Options.JavaScriptEnabled = false;
            client.Options.CssEnabled = true;
            client.Options.ThrowExceptionOnScriptError = false;
            client.Options.Timeout = 5000;

            HtmlPage page = client.GetHtmlPage("http://www.pbc.gov.cn/publish/zhengcehuobisi/637/index.html");
            Thread.Sleep(3000);
            string xml = page.AsXml();

            //string nodeName = doc.GetElementbyId("container").Name;
            Console.WriteLine(xml);
            Console.Read();
        }
    }
}

然而,NHtmlUnit应该也是失败了。。。

20分
你有两种办法解决,一个是用fiddlercore,直接拦截http数据。

另一个是分析一下抓包的过程,你会发现浏览器请求了三次http://www.pbc.gov.cn/publish/zhengcehuobisi/637/index.html
第一次获取cookie,第二次302跳转,第三次带着前两次的cookie访问网站,就给出来数据了

Cookie: wzwsconfirm=e8c83b5c7829fad0c6e16c1de47eb246; wzwstemplate=Ng==; wzwschallenge=-1; ccpassport=c14b5f460dcd23a4fddff3881ab60e29

引用 9 楼 liucqa 的回复:

你有两种办法解决,一个是用fiddlercore,直接拦截http数据。

另一个是分析一下抓包的过程,你会发现浏览器请求了三次http://www.pbc.gov.cn/publish/zhengcehuobisi/637/index.html
第一次获取cookie,第二次302跳转,第三次带着前两次的cookie访问网站,就给出来数据了

Cookie: wzwsconfirm=e8c83b5c7829fad0c6e16c1de47eb246; wzwstemplate=Ng==; wzwschallenge=-1; ccpassport=c14b5f460dcd23a4fddff3881ab60e29

这个cookie是会变的,所以每次得重新获取,请问有没有什么获取的思路啊,拜托了,被这玩意折磨死了。。。

分两次吧,WebBrowser加载页面,等加载完了后,延迟几秒将数据写到Queue中,另一个线程读取Queue中的字符串,然后用正则
引用 10 楼 u013281916 的回复:
Quote: 引用 9 楼 liucqa 的回复:

你有两种办法解决,一个是用fiddlercore,直接拦截http数据。

另一个是分析一下抓包的过程,你会发现浏览器请求了三次http://www.pbc.gov.cn/publish/zhengcehuobisi/637/index.html
第一次获取cookie,第二次302跳转,第三次带着前两次的cookie访问网站,就给出来数据了

Cookie: wzwsconfirm=e8c83b5c7829fad0c6e16c1de47eb246; wzwstemplate=Ng==; wzwschallenge=-1; ccpassport=c14b5f460dcd23a4fddff3881ab60e29

这个cookie是会变的,所以每次得重新获取,请问有没有什么获取的思路啊,拜托了,被这玩意折磨死了。。。

这有什么难的,用fiddler抓包看看数据格式,然后模拟提交就行

用HttpAnalyzer抓包,看下请求地址就行。
主要还是10#楼大神说的对~
80分
根据大神的指示,发现只要带着正确的“wzwsconfirm”,“wzwstemplate”,“wzwschallenge”三个cookie,访问网站,网站会302跳转并反馈“ccpassport”的cookie,有了这个就能正常取数据了。具体的可以用httpwebrequest来做,加上cookiecontainer就行了,这里不多罗嗦了。
关键是如何算出那三个cookie,两个方法,一是取回js代码,设法让在C#中执行,这个你已经在做了;另一个就是把js的代码转成C#的,下面就是转好的代码,当然质数表将是我长期的痛。。。
        private string Doubi1(string wzwschallenge, string wzwschallengex, int prefixlabel)
        {
            char[] tmp = (wzwschallenge + wzwschallengex).ToCharArray ();
            int[] zhishu={2,3,5,7,11,13,17,19,23,29,31};
            int hash = 0;
            int i = 0;
            for (i = 0; i < tmp.Length; i++)
            {
                hash += (int)tmp[i];
            }
            hash *= zhishu[prefixlabel];// 3;
            hash += 111111;
            return "WZWS_CONFIRM_PREFIX_LABEL" + prefixlabel + hash;
        }
        private string Doubi2(string str)
        {
            string outstr;
            int i, len,c1, c2, c3;
            char[] encoderchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".ToCharArray ();
            char[] strchar = str.ToCharArray();
            len = str.Length;
            i = 0;
            outstr= "";

            while (i < len)
            {
                c1 = (int)strchar[i++] & 0xff;
                if (i == len) 
                {
                    outstr += encoderchars[c1 >>2];
                    outstr += encoderchars[(c1 & 0x3) << 4];
                    outstr += "==";
                    break;
                }

                c2 = (int)strchar[i++];
            if (i == len)
            {
                outstr += encoderchars[c1 >> 2];
                outstr += encoderchars[((c1 & 0x3) << 4) | ((c2 & 0xf0) >> 4)];
                outstr += encoderchars[(c2 & 0xf) << 2];
                outstr += "=";
                break;
            }
            c3 = (int)strchar[i++];
            outstr += encoderchars[c1 >> 2];
            outstr += encoderchars[((c1 & 0x3) << 4) | ((c2 & 0xf0) >> 4)];
            outstr += encoderchars[((c2 & 0xf) << 2) | ((c3 & 0xc0) >> 6)];
            outstr += encoderchars[c3 & 0x3f];

            } 
            return outstr;
        }
引用 14 楼 xuqiang007 的回复:

主要还是10#楼大神说的对~

是9楼

通过Webbrowser把超链接都抓出来,然后在其他Webbrowser打开超链接,然后抓取id=”zoom”里面的内容,保存到数据库
cookie需要自己算吗?C#也可以调用js的
引用 18 楼 liucqa 的回复:

cookie需要自己算吗?C#也可以调用js的

是的,大神。不用算,直接調用js就妥妥了。

这个问题,从来没研究过,学习了
再补充一下,人家网站用的360网站卫士,里面那段js加密字符串,用的是base64,C#自带。
        private string Base64encode(string str)
        {
            byte[] bytes = Encoding.Default.GetBytes(str);
            str = Convert.ToBase64String(bytes);
            return str;
        }

一觉醒来突然想起来了。。。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明网站爬虫问题