imldy 发表于 2021-3-14 15:51

【Python】批量屏蔽知乎官方账号(机构号)的Python脚本

本帖最后由 imldy 于 2021-3-14 22:18 编辑

## 批量屏蔽知乎官方账号(机构号)的Python脚本

本文首发于www.52pojie.cn`@imldy`

### 痛点

知乎官方账号经常会推送一些广告到用户的账户,令人烦不胜烦,好几十个知乎官方账户一个一个手动屏蔽太麻烦。


### 解决办法

遂写了这个可以批量屏蔽的脚本,刚注册52账户,分享给大家。

### 脚本原理

通过知乎搜索接口搜索关键字“知乎”,对返回的结果当中的账号信息进行分析,如果满足可以认为是知乎官方账户的条件,就调用屏蔽API进行屏蔽。

### 脚本特点

自动获取搜索结果的5-20页,自动判断是否已经拉黑此账号,自动判断是否继续查找,自动判断是否符合知乎官方账户的特点。

### 运行平台:

编程语言:Python3
系统要求:跨平台(Windows/MacOS/Linux)

### 运行截图:
图1、自动搜索账号、自动判断



图2、自动屏蔽(注:这里是刚截的图,实际上我前几天刚写完脚本就屏蔽了一大堆,所以这次就发现/屏蔽了3个)



图3、黑名单列表(可以看到一大堆被我屏蔽的知乎账号)



### 使用方式:
#### 登录方式

暂不支持通过账户密码登录。需要手动抓包复制cookie,然后脚本同目录创建一个名为`cookies.txt`的文件,将复制的cookie粘贴到文件中。

#### 运行方式

有Python3解析器的朋友直接命令行/cmd执行`python block-all.py`或者`python3 block-all.py`

#### 注意

存在少许BUG、可能会有误伤/遗漏,不过比较少,可以手动进行弥补。

### 脚本代码

#### 下载附件



#### 或者直接复制代码

```python
# www.52pojie.cn @imldy
import time
import requests
from requests.cookies import cookiejar_from_dict


def convert_cookies_to_dict(cookies):
    cookies = dict()
    return cookies


class User:
    def __init__(self):
      self.session = requests.session()

    def sign_in(self, cookies=None, account_info=None):
      if cookies != None:
            self.session.cookies = cookiejar_from_dict(convert_cookies_to_dict(cookies))
      else:
            print("暂时仅支持cookies登录")
            pass

    def get_account_detail(self, zhihu_org):
      resp = self.session.get(zhihu_org["url"])
      result = resp.json()
      return result

    def filter(self, zhihu_org):
      '''
      传入的账号符合知乎官方机构号的特征就返回True
      :param zhihu_org:
      :return:
      '''
      print(zhihu_org["account_name"], end="\t")
      print(zhihu_org["account_url_token"], end="\t")
      print(zhihu_org["user_type"], end="\t")
      if (zhihu_org["account_name"][:2].startswith("知乎", 0, 2)) \
                and (
                zhihu_org["account_url_token"].startswith("zhi-hu", 0, 6) or zhihu_org["account_url_token"].startswith(
            "zhihu_", 0, 6)) \
                and (zhihu_org["user_type"] == "organization"):
            if self.get_account_detail(zhihu_org)["is_blocking"]:
                print("已屏蔽此账号,跳过")
            else:
                print("符合要求")
                return True
      else:
            print("!!!不符合要求")
            return False

    def get_all_zhihu_org(self):
      self.session.headers["referer"] = "https://www.zhihu.com/search?q=%E7%9F%A5%E4%B9%8E&type=people"
      self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36 Edg/89.0.774.45"})
      zhihu_org_list = []
      flag = 0
      search_api_url = "https://api.zhihu.com/search_v3?advert_count=0&correction=1&lc_idx=0&limit=20&offset=0&q=%E7%9F%A5%E4%B9%8E&show_all_topics=0&t=people"
      after_len = 0
      while flag < 20:
            flag += 1
            resp = self.session.get(search_api_url)
            result = resp.json()
            if result["paging"]["is_end"] == True:
                print("查找到底了,第{}页".format(flag))
                break
            for i in result["data"]:
                zhihu_org = {
                  "account_name": i["object"]["name"].replace("<em>", "").replace("</em>", ""),
                  "account_url_token": i["object"]["url_token"],
                  "user_type": i["object"]["user_type"],
                  "url": i["object"]["url"]# 系列信息的API
                }
                if self.filter(zhihu_org):
                  # 符合要求(知乎官方机构号的特征)才加入列表
                  zhihu_org_list.append(zhihu_org.copy())
            now_len = len(zhihu_org_list)
            print("当前第{}页,列表长度:{}".format(flag, now_len))
            if after_len == now_len and flag > 5:
                # 即列表长度相较于上一次没变,代表没有发现新的知乎账号,就结束获取账号的操作
                print("找到了{}页,没有发现新的知乎官方账号,结束查找,已找到{}个".format(flag, now_len))
                break
            else:
                # 变化了,就开始下一轮
                after_len = now_len
            # 下一页的链接
            search_api_url = result["paging"]["next"]
            time.sleep(1)
      return zhihu_org_list

    def block_all_zhihu_org(self, zhihu_org_list):
      num = 0
      for zhihu_org in zhihu_org_list:
            num += 1
            print("3秒后开始屏蔽:{} {}/{}".format(zhihu_org["account_name"], num, len(zhihu_org_list)))
            time.sleep(3)
            self.block_zhihu_org(zhihu_org)

    def block_zhihu_org(self, zhihu_org):
      block_api_url = "https://www.zhihu.com/api/v4/members/{}/actions/block".format(zhihu_org["account_url_token"])
      resp = self.session.post(block_api_url)
      if resp.status_code == 204:
            print("屏蔽成功:{}".format(zhihu_org["account_name"]))
            return True


if __name__ == '__main__':
    account_info = {
      "username": "",
      "password": ""
    }
    cookies_file = "cookies.txt"
    cookies = open(cookies_file).read()
    zhihu_user = User()
    zhihu_user.sign_in(cookies)
    print("正在获取要屏蔽的列表")
    zhihu_org_list = zhihu_user.get_all_zhihu_org()
    print("列表获取完成,开始屏蔽")
    zhihu_user.block_all_zhihu_org(zhihu_org_list)

```

**新人第一次发帖,希望批评指正**

另外问下大佬们,是不是过了新人期才能设置回复可见/出售附件啊,我发帖的时候没找到相应设置,新人太穷了。

更新:因为管理员将此贴移动到了“Python”分类,作为新人看了一下编程语言区版规的“标题标准规范”,发现非原创的内容才需要选择具体语言的分类,原创的选择“原创源码”分类且标题注明使用语言即可,所以我编辑一下。

沧浪之水濯我心 发表于 2021-3-22 15:33

我试了一下 挺不错的 收藏了

imldy 发表于 2021-3-22 22:58

沧浪之水濯我心 发表于 2021-3-22 15:33
我试了一下 挺不错的 收藏了

感谢支持:lol

c542134 发表于 2022-11-7 10:15

有没有shua点赞和评论的?
页: [1]
查看完整版本: 【Python】批量屏蔽知乎官方账号(机构号)的Python脚本