python中∧是什么意思_10291 用Python忽略全部邀请

.

昨晚写了一个 Python 程序,可以自动忽略知乎上的全部邀请。欢迎大 V 们试用!

下面是原理介绍。

一、忽略邀请时发生了什么

在“邀请我回答的问题”页面(下文简称“邀请页面”),点击一个邀请后的“忽略”按钮,可以发现这个邀请消失了,但页面并没有刷新。由此推测,点击“忽略”按钮时页面向服务器发送了一个 AJAX 请求。

在 Chrome 中按 F12 键调出开发者工具窗口,并切换至 Network → XHR 标签页。再点击一个邀请后的“忽略”按钮,发现果然出现了一个请求。

  查看该请求的细节可以发现,这是一个 POST 请求,目标 URL 是 https://www.zhihu.com/question/askpeople,并带有如下的表单数据:

这里,op 表示操作, pass 应该就是“忽略”的意思。qid 是一个八位十进制数,代表问题的编号,你在浏览问题页面时,URL 最后的八位数字就是它。uid 是一个 32 位十六进制数,代表了用户的身份。_xsrf 是 cross-site request forgery(跨站请求伪造)的缩写,也是一个 32 位十六进制数,用来告诉服务器这确实是你本人在操作。

利用 Unix 或 Cygwin 中的 curl 工具,可以在命令行发送 POST 请求,如下。当然,这里的 qid 要换成下一个邀请的编号。

结果返回一串乱码,刷新邀请页面,发现邀请并未消失。这是因为刚刚发送的 POST 请求不带 cookies,被服务器拒绝了。

在 Cookies 标签页下可以找到浏览器发送的 POST 请求所带有的 cookies,它们是各种意味不明的字符串。经试验,其中只有 _xsrf 和 z_c0 两项是必需的;_xsrf 的值与表单参数中的相同。把这两个 cookies 添加到用 curl 发送的 POST 请求中去,发现返回一个 json 对象;刷新邀请页面,第一个邀请果然就消失了。

二、批量忽略邀请

弄懂了忽略一个邀请是怎么操作的,就容易写出批量忽略邀请的脚本了。首先模拟登录,然后反复读取邀请页面(页面上会有最近的 20 个邀请),提取出页面上的问题编号,逐一发送 POST 请求忽略,直到不再有邀请为止。

利用 Python 里的 requests 库,可以发送 GET 或 POST 请求。与 curl 不同,它发送的请求必须带有 headers,不过我发现,必需的 headers 只有 User-Agent 这一项,而且值为空就行。 requests 库里有个 Session 类,其对象可以把 cookies 记忆起来,于是手动提取 _xsrf 和 z_c0 两项 cookies 的工作就可以省去了。

下面是各个步骤的做法,和它们的返回结果:模拟登录:需要向 https://www.zhihu.com/login/email 页面发送一个 POST 请求,表单数据只需要 email(账号)和 password(密码),并不需要 captcha(验证码)。如果登录成功,会返回状态码 200(OK)和一个 json 对象,其中 msg(消息)项的值为字符串“登陆成功”(是的,有错别字)。

读取邀请页面:只需向 https://www.zhihu.com/question/invited 发送一个 GET 请求,不需要任何表单数据。如果读取成功,会返回状态码 200(OK)和 HTML 格式的页面内容。由于我在手工打开邀请页面的时候,经常遇到 500 页面(“服务器提了一个问题”),所以我的脚本会重复读取直至成功。

忽略邀请:需要向 https://www.zhihu.com/question/askpeople 发送一个 POST 请求,表单数据包括 op(值为 pass)、qid(问题编号)、uid(用户身份)、_xsrf。Cookies 由 Session 对象自动搞定。如果忽略成功,会返回状态码 200(OK)和一个 json 对象 {"r": 0, "msg": ""}。

忽略邀请时所需的 qid、uid、_xsrf 三项数据,都可以在邀请页面中找到。qid 就在邀请本身里面,在附近还可以找到邀请者的信息。uid 在页面中的一处脚本里,是“user_hash”后面的一串十六进制数;_xsrf 在页面底部的一个隐藏输入框里。

  使用 BeautifulSoup 库,可以将 HTML 页面解析成树形结构,方便地提取上面所需的各项数据。

有了上面的准备,就可以写脚本了。忽略一个邀请大约用时 0.5 秒,效率还可以。不过,当忽略了几百个邀请后,我发现我的知乎账号因为访问太快被暂时冻结了╮( ̄▽ ̄)╭,不过好在 1 个多小时后就恢复了正常。在现在的版本中,我只能每 5 秒忽略一个邀请,并在忽略 20 个页面(400 个邀请)后休息 1 分钟。

三、隐藏的“全部忽略”功能?

我在探索的过程中,意外地发现知乎可能有未公开的“全部忽略”功能。我是这么发现的:

首先,我试图定位忽略邀请的 POST 请求是在哪里发起的。邀请页面上的“忽略”按钮(其实是个超链接),其 href 值为“javascript:;”,也就是说发起 POST 请求的代码并不在此处。我依次打开邀请页面所加载的各个 JavaScript 文件,并搜索“askpeople”、“pass”等关键字,最终发现发起 POST 请求的代码位于 https://www.zhihu.com/static/revved/-/js/closure/page-misc.13415dac.js 这个脚本中。将脚本美化后,我发现了这样几个函数:

  其中 z.e.Zo 就是发起忽略邀请的 POST 请求的函数。但是,从 z.e.Pa 和 z.e.sQ 两个函数来看,https://www.zhihu.com/question/askpeople 这个地址还提供了“恢复邀请”和“忽略全部邀请”的功能,z.e.C 甚至表明页面上本应有一个“忽略全部邀请”的按钮!然而,当我试着用 curl 发送“忽略全部邀请”的 POST 请求(op = ignore_all,无 qid 参数)时,却得到了“服务器提了一个问题”的页面。

不知道知乎可不可以把这个“忽略全部邀请”功能公开出来呢?⊂(●∧●)⊃ @知乎小管家

四、参考文献

我在写脚本的过程中参考了下面两篇文章,在此向作者致谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值