相信大家在微信上一定被上面的这段话刷过屏,群发消息应该算是微信上流传最广的找到删除好友的方法了。但群发消息不仅仅会把通讯录里面所有的好友骚扰一遍,而且你还得挨个删除好几百个聊天记录,回复大家的疑问和鄙视。作为一个互联网从业者,除了群发消息就不能有更高效、不打扰好友的方式么?

答案是当然有,本人的微:1613161916可以一起讨论python,还有许多Python资料可以发送。

微信在拉好友进群聊的时候,如果这个人删除了你好友的话,会提示你一下「请先发送朋友验证申请给某某,对方将你加为微信朋友后,你才能邀请其加入群聊。」有办法了,那我把微信好友拉一个大群里面,然后默默的删掉微信群不就好了么。

于是 Github 上就有一位叫 0x5e 的开发者写了这么一个 Python 脚本来代替你手动拉群和踢人。经过笔者测试,目前只能支持 Mac 的操作系统。在此之前,笔者在稀土掘金上先放出了Github的方法,这里再详细提下。

在 0x5e 的 Github 代码仓库描述里面,他具体的实现步骤是用 Python 脚本处理网页版微信的拉群、踢人操作。具体的步骤如下:

  • 下载代码文件 wdf.py
  • 打开 Terminal 输入:python 然后拖动刚才下载的 wdf.py 到 Terminal 窗后回车。命令格式类似: python wdf.py
  • 接下来按步骤扫码操作即可;

查询结果可能会引起一些心理上的不适,请小心使用。

笔者测试了两次,这个 Python 脚本还是有一些小问题,欢迎开发者们给原作者发 Pull Request 完善:

  • 两次结果稍有出入,可能是微信网页版返回数据的问题
  • 最终在微信会遗留一个只有自己的群组,需要手动删除
  • 此脚本暂时不支持查找被拉黑的情况

源码

#!/usr/bin/env python
# coding=utf-8
 
from __future__ import print_function
 
import os
import requests
import re
import time
import xml.dom.minidom
import json
import sys
import math
import subprocess
import ssl
import threading
 
DEBUG = False
 
MAX_GROUP_NUM = 2 # 每组人数
INTERFACE_CALLING_INTERVAL = 5 # 接口调用时间间隔, 间隔太短容易出现"操作太频繁", 会被限制操作半小时左右
MAX_PROGRESS_LEN = 50
 
QRImagePath = os.path.join(os.getcwd(), 'qrcode.jpg')
 
tip = 0
uuid = ''
 
base_uri = ''
redirect_uri = ''
push_uri = ''
 
skey = ''
wxsid = ''
wxuin = ''
pass_ticket = ''
deviceId = 'e000000000000000'
 
BaseRequest = {}
 
ContactList = []
My = []
SyncKey = []
 
try:
  xrange
  range = xrange
except:
  # python 3
  pass
 
 
def responseState(func, BaseResponse):
  ErrMsg = BaseResponse['ErrMsg']
  Ret = BaseResponse['Ret']
  if DEBUG or Ret != 0:
    print('func: %s, Ret: %d, ErrMsg: %s' % (func, Ret, ErrMsg))
 
  if Ret != 0:
    return False
 
  return True
 
 
 
def getUUID():
  global uuid
 
  url = 'https://login.weixin.qq.com/jslogin'
  params = {
    'appid': 'wx782c26e4c19acffb',
    'fun': 'new',
    'lang': 'zh_CN',
    '_': int(time.time()),
  }
 
  r= myRequests.get(url=url, params=params)
  r.encoding = 'utf-8'
  data = r.text
 
  # print(data)
 
  # window.QRLogin.code = 200; window.QRLogin.uuid = "oZwt_bFfRg==";
  regx = r'window.QRLogin.code = (\d+); window.QRLogin.uuid = "(\S+"'
  pm = re.search(regx, data)
 
  code = pm.group(1)
  uuid = pm.group(2)
 
  if code == '200':
    return True
 
  return False
 
 
def showQRImage():
  global tip
 
  url = 'https://login.weixin.qq.com/qrcode/' + uuid
  params = {
    't': 'webwx',
    '_': int(time.time()),
  }
 
  r = myRequests.get(url=url, params=params)
 
  tip = 1
 
  f = open(QRImagePath, 'wb')
  f.write(r.content)
  f.close()
  time.sleep(1)
 
  if sys.platform.find('darwin') >= 0:
    subprocess.call(['open', QRImagePath])
  elif sys.platform.find('linux') >= 0:
    subprocess.call(['xdg-open', QRImagePath])
  else:
    os.startfile(QRImagePath)
 
  print('请使用微信扫描二维码以登录')
 
 
def waitForLogin():
  global tip, base_uri, redirect_uri, push_uri
 
  url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login"(\S+";'
    pm = re.search(regx, data)
    redirect_uri = pm.group(1) + '&fun=new'
    base_uri = redirect_uri[:redirect_uri.rfind('/')]
 
    # push_uri与base_uri对应关系(排名分先后)(就是这么奇葩..)
    services = [
      ('wx2.qq.com', 'webpush2.weixin.qq.com'),
      ('qq.com', 'webpush.weixin.qq.com'),
      ('web1.wechat.com', 'webpush1.wechat.com'),
      ('web2.wechat.com', 'webpush2.wechat.com'),
      ('wechat.com', 'webpush.wechat.com'),
      ('web1.wechatapp.com', 'webpush1.wechatapp.com'),
    ]
    push_uri = base_uri
    for (searchUrl, pushUrl) in services:
      if base_uri.find(searchUrl) >= 0:
        push_uri = 'https://%s/cgi-bin/mmwebwx-bin' % pushUrl
        break
 
    # closeQRImage
    if sys.platform.find('darwin') >= 0: # for OSX with Preview
      os.system("osascript -e 'quit app \"Preview\"'")
  elif code == '408': # 超时
    pass
  # elif code == '400' or code == '500':
 
  return code
 
 
def login():
  global skey, wxsid, wxuin, pass_ticket, BaseRequest
 
  r = myRequests.get(url=redirect_uri)
  r.encoding = 'utf-8'
  data = r.text
 
  # print(data)
 
  doc = xml.dom.minidom.parseString(data)
  root = doc.documentElement
 
  for node in root.childNodes:
    if node.nodeName == 'skey':
      skey = node.childNodes[0].data
    elif node.nodeName == 'wxsid':
      wxsid = node.childNodes[0].data
    elif node.nodeName == 'wxuin':
      wxuin = node.childNodes[0].data
    elif node.nodeName == 'pass_ticket':
      pass_ticket = node.childNodes[0].data
 
  # print('skey: %s, wxsid: %s, wxuin: %s, pass_ticket: %s' % (skey, wxsid,
  # wxuin, pass_ticket))
 
  if not all((skey, wxsid, wxuin, pass_ticket)):
    return False
 
  BaseRequest = {
    'Uin': int(wxuin),
    'Sid': wxsid,
    'Skey': skey,
    'DeviceID': deviceId,
  }
 
  return True
 
 
def webwxinit():
 
  url = (base_uri + 
    '/webwxinit"newsapp", "fmessage", "filehelper", "weibo", "qqmail", "tmessage", "qmessage", "qqsync", "floatbottle", "lbsapp", "shakeapp", "medianote", "qqfriend", "readerapp", "blogapp", "facebookapp", "masssendapp",
          "meishiapp", "feedsapp", "voip", "blogappweixin", "weixin", "brandsessionholder", "weixinreminder", "wxid_novlwrv3lqwv11", "gh_22b87fa7cb3c", "officialaccounts", "notification_messages", "wxitil", "userexperience_alarm"]
  for i in range(len(MemberList) - 1, -1, -1):
    Member = MemberList[i]
    if Member['VerifyFlag'] & 8 != 0: # 公众号/服务号
      MemberList.remove(Member)
    elif Member['UserName'] in SpecialUsers: # 特殊账号
      MemberList.remove(Member)
    elif Member['UserName'].find('@@') != -1: # 群聊
      MemberList.remove(Member)
    elif Member['UserName'] == My['UserName']: # 自己
      MemberList.remove(Member)
 
  return MemberList
 
 
def createChatroom(UserNames):
  MemberList = [{'UserName': UserName} for UserName in UserNames]
 
  url = (base_uri + 
    '/webwxcreatechatroom"0",selector:"2"}
  regx = r'window.synccheck={retcode:"(\d+)",selector:"(\d+)"}'
  pm = re.search(regx, data)
 
  retcode = pm.group(1)
  selector = pm.group(2)
 
  return selector
 
 
def webwxsync():
  global SyncKey
 
  url = base_uri + '/webwxsync"无")
  print('---------------------------------------------')
 
 
# windows下编码问题修复
# http://blog.csdn.net/heyuxuanzee/article/details/8442718
 
class UnicodeStreamFilter:
 
  def __init__(self, target):
    self.target = target
    self.encoding = 'utf-8'
    self.errors = 'replace'
    self.encode_to = self.target.encoding
 
  def write(self, s):
    if type(s) == str:
      try:
        s = s.decode('utf-8')
      except:
        pass
    s = s.encode(self.encode_to, self.errors).decode(self.encode_to)
    self.target.write(s)
 
if sys.stdout.encoding == 'cp936':
  sys.stdout = UnicodeStreamFilter(sys.stdout)
 
if __name__ == '__main__':
 
  print('本程序的查询结果可能会引起一些心理上的不适,请小心使用...')
  print('1小时内只能使用一次,否则会因操作繁忙阻止建群')
  main()
  print('回车键退出...')
  input()

广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!

稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!

昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。

这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。

而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?