python爬虫js加密篇—搜狗微信公号文章的爬取

今天这篇文章主要介绍的是关于微信公众号文章的爬取,其中里面主要涉及的反爬机制就是js加密与cookies的设置

微信公众号的上一个版本中的反爬机制中并没有涉及到js加密,仅通过监控用户ip,单个ip访问太频繁会面临被封的风险;在新的版本中加入了js加密反爬机制,接下来我们来逐步分析一下文章爬取过程

打开搜狗页面搜狗微信页面,在输入框中输入任意关键词例如火车隧道起火,搜出来的都是涉及关键词的公号文章列表

这里按照平常套路,直接利用开发者工具的选择工具,查看源码中列表中每篇文章的url,就是下面这个href属性标签,

看到这个url,按照正常思路的话,就是直接做url拼接:搜狗主域名 + href就是微信主要内容的url,形式如下

https://weixin.sogou.com/link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgS_yBZajb90fWf-LwgFP7QmnFtbELADqFzFqXa8Fplpd9nrYbnf-BG6fJQmhdTDKRUQC_zVYwjAHQRnKwtfQUOD-aNBz2bhtCuShQywQb837B12cBkYFsYkKXir7Y9WqlRBcZIrhUAYmFlBSVIg7YGFbBdu4rXklGlRslEFpw0lTmIX8pHfpQ9x6clCHaA92qoA9YOaIV2yOyrE-focNFXq7wdVqCwyPdzA..&type=2&query=%E7%81%AB%E8%BD%A6%E9%9A%A7%E9%81%93%E8%B5%B7%E7%81%AB

但是直接点这个链接返回的是402页面,需要输入验证码进行验证,而且验证码通过后依然进不去;很明显这个url并不是文章的访问入口

经过测试,这篇文章的真实url是下面这种形式(直接通过点击页面标签打开即可):

https://mp.weixin.qq.com/s?src=11&timestamp=1567073292&ver=1820&signature=z2h7E*HznopGFidmtUA4PmXgi3ioRqV7XiYIqn9asMT3RCMKss6Y2nPUh7RG63nrwmRii77cL9LyDNJIVp1qpo5LHvQ8s754Q9HtCgbp5EPUP9HjosY7HWDwze6A2Qi7&new=1

是不是很很意外;这里开始就需要转变思路:不管怎样最好先抓一下包,这里我利用的工具是Fidder,关于Fidder如何使用,可以参照这篇文章:

先从搜索页面的文章列表中进入文章的详情页,我们需要通过Fidder来监控一下文章的跳转情况:

看到没,惊奇地发现有个/link?url开头的url跳转成功了,深入一下,我们再看一下这个链接返回的是什么,点一下response部分的TextView;


返回的text文本是一串字符串组成的,即使不懂javascript,但里面大概意思就是构造一个url,格式与前面那个真实的url有一些相似呢,经测试之后发现,返回的这个url就是获取文章内容的真实url

把这个访问成功的并且以link?url开头的url完整复制下来,与源码中的那个link?url放在一起,发现这个访问成功的url中多了两个参数一个是k一个是h

# 访问成功的:https://weixin.sogou.com/link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgS_yBZajb90fWf-LwgFP7QmnFtbELADqFzFqXa8Fplpd9nrYbnf-BG6fJQmhdTDKRUQC_zVYwjAHQRnKwtfQUOD-aNBz2bhtCuShQywQb837B12cBkYFsYkKXir7Y9WqlRBcZIrhUAYmFlBSVIg7YGFbBdu4rXklGlRslEFpw0lTmIX8pHfpQ9x6clCHaA92qoA9YOaIV2yOyrE-focNFXq7wdVqCwyPdzA..&type=2&query=%E7%81%AB%E8%BD%A6%E9%9A%A7%E9%81%93%E8%B5%B7%E7%81%AB&k=80&h=f

# 访问失败的:https://weixin.sogou.com/link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgS_yBZajb90fWf-LwgFP7QmnFtbELADqFzFqXa8Fplpd9nrYbnf-BG6fJQmhdTDKRUQC_zVYwjAHQRnKwtfQUOD-aNBz2bhtCuShQywQb837B12cBkYFsYkKXir7Y9WqlRBcZIrhUAYmFlBSVIg7YGFbBdu4rXklGlRslEFpw0lTmIX8pHfpQ9x6clCHaA92qoA9YOaIV2yOyrE-focNFXq7wdVqCwyPdzA..&type=2&query=%E7%81%AB%E8%BD%A6%E9%9A%A7%E9%81%93%E8%B5%B7%E7%81%AB

现在基本爬取核心思路已经知道了,主要就是破解这两个参数k和h,拼接成'真'的url(以/cl.gif开头的),然后获取真url;

关于这两个参数的破解就是涉及到了js加密,需要进行调试,不懂的可以参考这篇文章:Chrome DevTools 中调试 JavaScript 入门;

第一步,回到源码中link?url位置的地方,因为后面两个参数的增加是由于我们触发了这个假的url,所以这里需要对假的url进行监听:

开发者工具[Elements] -> 右上角处的[Event Listeners] -> [click] -> 你需要监控的元素标签

第二步,按流程浏览完上面所有过程时下面会有个js文件,点进去,并对js代码进行格式化,发现参数k与h的构造方法:

其实还有一种参数定位的方法,在Google开发者选项中利用全局搜索[Search]就能快速定位,但是并不适用于这里,因为这里我们定位的参数都是单个元素,定位的准确度特别低

定位之后,参数kh的定义非常清楚,没有过多函数嵌套,就是在一个简单的函数中,一个是生成一个随机数字,另一个在这个href标签的链接中获取其中的某一个字符,这里我们可以直python把这个功能实现:

url_list11  = pq(res.text)('.news-list li').items()

    for i in url_list11:

        url_list12 = pq(i('.img-box a').attr('href'))

        url_list12 =str(url_list12).replace('<p>','').replace('</p>','').replace('amp;','')

        print(url_list12)

        b = int(random.random() * 100) + 1

        a = url_list12.find("url=")

        result_link = url_list12 + "&k=" + str(b) + "&h=" + url_list12[a + 4 + 21 + b: a + 4 + 21 + b + 1]

        a_url ="https://weixin.sogou.com" +result_link

好了,‘真’url也能够构造成功了,通过访问‘真’url来获取真url(访问时记得加上headers),然后再获取我们需要的信息;然而结果却是下面这样的:

经测试发现,原因是由于Cookie中最为核心的两个参数SUV和SUNID,而这两个参数在不断地发生改变

其中SUNID有固定得访问次数/时间限制,超过了限制直接变为无效,并且当访问网页请求失败后,SUNID与SUV需要更换才能再次正常访问;

SUV参数是在‘真’url过度到真url中某个网页中Response里的Set-Cookie中生成的,也就是下面这个网页:

需要我们请求这个链接,通过这个链接返回的Cookie,我们拿到这个Cookie放入请求头里面,再访问拼接好的* ‘真’ url*

最后就能获取到真url最后请求这个链接,解析出我们想要的数据(注意用请求头的时候最好不要加Cookies,否则会导致访问失败)当解决以上所有问题了,这里再测试一下,已经能够成功地拿到我们想要的数据:

上面是部分板块代码,想要获取全部源码,关注微信公众号:zeroing说;后台回复关键词:搜狗即可。

def get_suva(sunid):

    '''

    根据sunid来获取suv参数;并添加到cookie众

    :param a: sunid

    :return:

    '''

    b_data['snuid'] = sunid.split('=')[-1]

    b_data['uuid'] = uuid.uuid1()

    b_data['uigs_t'] = str(int(round(time.time() * 1000)))

    url_link = 'https://pb.sogou.com/pv.gif?' + urlencode(b_data)

    res = requests.get(url_link)

    cookie_s = res.headers['Set-Cookie'].split(',')

    cookie_list_s = []

    for i in cookie_s:

        for j in i.split(','):

            if 'SUV' in j:

                cookie_list_s.append(j)

            else:

                continue

    print(cookie_list_s[0].split(';')[0])

    headers['Cookie'] = cookie_list_s[0].split(';')[0]

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容