微博爬虫——自动获取访客Cookie - GXUZF.COM - 林澈思的茶

微博爬虫——自动获取访客Cookie

分类:折腾 ; 热度:5711 ; 最后更新于2020 年 02 月 14 日

赵帆同学赵帆同学
简介面对微博的Sina Visitor System,我们该如何有效的绕过呢?本文将介绍一种绕过Sina Visitor System的方法。

0、前言


做过微博爬虫的应该都知道微博存在一个Sina Visitor System,即无需登录就能访问的页面,也需要获得一个访客cookie才能访问。如果我们直接对微博页面爬取,那么返回的页面全都是Sina Visitor System的页面。

因此,我们在这里分析一下Sina Visitor System生成访客Cookie的原理,同时实现自动化获取有效访客Cookie,以此绕过微博Sina Visitor System系统。

1、Sina Visitor System原理


1.1、基本流程


首先,我们看一下加载微博界面的整个流程。这里我们随便选取了一个用户的页面作为展示:

4a47a0db6e60853dedfcfdf08a5ca249.png

可以看到,中间红框部分就是新浪访客系统分配访客Cookie的过程。我们只要分析一下整个过程工作的原理,就可以自动化获取到足够多的访客Cookie,以此支持我们的爬虫可以不间断的爬取。

首先看一下红框中的第一个请求,这里就是Sina Visitor System。我们进去查看一下,在首部引入了一个js文件,可以发现这就是上述红框请求中第二个请求;然后就是下面部分中incarnate()是生成访客Cookie的。

fb5c81ed3a220004b71069645f112867.png

看一下incarnate()的内容,这里就是发送了一个GET请求,然后我们可以发现就是上述红框中第四个请求

10fb15c77258a991b0028080a64fb42d.png

因此,我们只要能成功的提交红框中第四个请求,就可以获取到一个访客Cookie。

1.2、tid的获取


看一下第四个请求的内容:

09dd8c2662b96ce14928333f055c5580.png

这里我们可以发现有很多个参数,在多次从测试对比中我们可以发现其中acbfromcw是固定的,_rand是一个随机数,gc一致是为空。因此我们只需要获取到tid的值就ok了。在上述源码页面中并不存在这几个值相关的代码,因此我们需要看其引入的js文件中是否存在,也就是红框中第二个请求。

8266e4bfeda1bd42d8f9794eb4ea0a13.png

f19c9085129709ee14d013be869df69b.png

可以发现,这里发送的请求就是上述红中的第三个请求,POST了两个参数,一个是cp,定值为:gen_callback;另一个是fp,他是通过getFp()方法生成,其大致是获取浏览器类型,窗口大小,字体之类的常量。因此这两个值我们都可以认为是个定值,在测试时只需要直接复制就OK了。

然后我们模拟提交一下这个请求,发现可以返回tid:

9eb9cd58b9ea5e04c890326b5c1f471f.png

至此我们已经成功获取到了第一个关键的参数——tid

1.3、Cookie的获取


然后就是发出我们最终的请求了,也就是红框中的第四个请求。注意:发送该请求时,我们需要加入一个Cookie: tid: tid__095

代码如图:

3c10253bf5e42d892ea0815b7f465e79.png

运行结果:

586e508f161f26ce94633729ac56c602.png

成功获取到了两个Cookie值:SUB和SUBP。

注意,这里有个缺陷,即我们并不能保证每次都可以获取到SUB和SUBP两个值。有时是获取不到的,获取失败时只需要重新获取就可以。

2、测试


我们在Cookie中加入这两个值进行测试,发现可以绕过Sina Visitor System,直接访问页面。

正常访问时的页面加载流程:

9eb60bc8bf2b004e4db7d1cc0d5f1d8c.png

加入Cookie时页面加载流程:

7b6fbd4c592d356e087a0f1053751007.png

可以看到,第一次需要经过Sina Visitor System加载,第二次页面直接加载,成功绕过Sina Visitor System。

3、简易代码


下面是一个简单的实现代码

  • # -*- coding:utf-8 -*-
  • # Author: Suummmmer
  • # Date: 2019-05-17
  • import requests
  • import random
  • headers = {
  • "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, "
  • "like Gecko) Chrome/69.0.3497.100 Safari/537.36",
  • }
  • def get_tid():
  • """
  • 获取tid,c,w
  • :return:tid
  • """
  • tid_url = "https://passport.weibo.com/visitor/genvisitor"
  • data = {
  • "cb": "gen_callback",
  • "fp": {
  • "os": "3",
  • "browser": "Chrome69,0,3497,100",
  • "fonts": "undefined",
  • "screenInfo": "1920*1080*24",
  • "plugins": "Portable Document Format::internal-pdf-viewer::Chrome PDF Plugin|::mhjfbmdgcfjbbpaeojofohoefgiehjai::Chrome PDF Viewer|::internal-nacl-plugin::Native Client"
  • }
  • }
  • req = requests.post(url=tid_url, data=data, headers=headers)
  • if req.status_code == 200:
  • ret = eval(req.text.replace("window.gen_callback && gen_callback(", "").replace(");", "").replace("true", "1"))
  • return ret.get('data').get('tid')
  • return None
  • def get_cookie():
  • """
  • 获取完整的cookie
  • :return: cookie
  • """
  • tid = get_tid()
  • if not tid:
  • return None
  • cookies = {
  • "tid": tid + "__095" # + tid_c_w[1]
  • }
  • url = "https://passport.weibo.com/visitor/visitor?a=incarnate&t={tid}"
  • "&w=2&c=095&gc=&cb=cross_domain&from=weibo&_rand={rand}"
  • req = requests.get(url.format(tid=tid, rand=random.random()),
  • cookies=cookies, headers=headers)
  • if req.status_code != 200:
  • return None
  • ret = eval(req.text.replace("window.cross_domain && cross_domain(", "").replace(");", "").replace("null", "1"))
  • try:
  • sub = ret['data']['sub']
  • if sub == 1:
  • return None
  • subp = ret['data']['subp']
  • except KeyError:
  • return None
  • return sub, subp

4、参考链接

https://blog.csdn.net/qq_41057280/article/details/81201337


评论卡