首頁>科技>

相信每個人的微信通訊錄裡都存在一些「殭屍粉」,他們默默地躺在聯絡人列表中,你以為對方還是朋友,那就真是太年輕、太天真的;實際上,對方早就把從好友列表中刪了,那如何來篩選出這群人呢?

這裡要注意:不管你是剛學Python還是想找python高薪工作,記住:專案開發經驗永遠是核心,如果你沒有python入門到高階實戰視訊教程,可以關注我,後臺私信我 ‘py’ 自動獲取最新python教程資料!還有老司機解答哦! 網上的很大量檢測殭屍粉的工具,檢測的時候會給微信通訊錄內的每一個好友傳送一條檢測資訊,嚴重「打擾」到對方;另外一部分軟體在檢測的時候,會植入一些程式碼病毒,暗箱操作顯得很不安全。

2、準 備 工 作

在開始編寫指令碼之前,需要做好如下準備工作

一部 Root 後的 Android 手機或者模擬器,如果沒有 Root 的裝置,推薦使用網易 MuMu 模擬器Android 開發環境、Android Studiosqlcipher 圖形化工具自動化工具:Python 虛擬環境下安裝 pocoui

3、編 寫 腳 本

//微信 App 的目錄public static final String WX_ROOT_PATH = "/data/data/com.tencent.mm/";/** * 執行linux指令 * * @param paramString*/public static void execRootCmd(String paramString){    try    {        Process localProcess = Runtime.getRuntime().exec("su");        Object localObject = localProcess.getOutputStream();        DataOutputStream localDataOutputStream = new DataOutputStream((OutputStream) localObject);        String str = String.valueOf(paramString);        localObject = str + "";        localDataOutputStream.writeBytes((String) localObject);        localDataOutputStream.flush();        localDataOutputStream.writeBytes("exit");        localDataOutputStream.flush();        localProcess.waitFor();        localObject = localProcess.exitValue();    } catch (Exception localException)    {        localException.printStackTrace();    }}//獲取許可權RootUtils.execRootCmd("chmod 777 -R " + WX_ROOT_PATH);

然後,獲取微信資料庫的密碼。

/** * 根據imei和uin生成的md5碼,獲取資料庫的密碼(去前七位的小寫字母) * * @param imei * @param uin * @return */public static String getDbPassword(String imei, String uin){    if (TextUtils.isEmpty(imei) || TextUtils.isEmpty(uin))    {        Log.d("xag", "初始化資料庫密碼失敗:imei或uid為空");        return "密碼錯誤";     }     String md5 = MD5Utils.md5(imei + uin);     assert md5 != null;     return md5.substring(0, 7).toLowerCase();}

接著,就可以使用 SQLCipher 依賴庫來對微信資料庫進行查詢,我們需要為專案新增如下依賴,方便操作資料庫。

//我們需要對專案增加依賴implementation 'net.zetetic:android-database-sqlcipher:3.5.4@aar'

利用上面得到的密碼開啟加密資料庫,然後查詢「rcontact」表獲取微信通訊錄內所有的好友的微訊號、暱稱、使用者名稱等資料。

/** * 連線資料庫 * <p> * 常用庫介紹:【rcontact】聯絡人表,【message】聊天訊息表 * * @param dbFile */private void openWxDb(File dbFile, String db_pwd){    //所有聯絡人    List<Contact> contacts = new ArrayList<>();    SQLiteDatabase.loadLibs(this);    SQLiteDatabaseHook hook = new SQLiteDatabaseHook()    {        public void preKey(SQLiteDatabase database)        {        }        public void postKey(SQLiteDatabase database)        {             atabase.rawExecSQL("PRAGMA cipher_migrate;"); //相容2.0的資料庫        }    };    try    {        //開啟資料庫連線        SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbFile, db_pwd, null, hook);         //查詢所有聯絡人         //過濾掉本人、群聊、公眾號、服務號等一些聯絡人         //verifyFlag != 0:公眾號、服務號         //注意黑名單使用者,我-設定-隱私-通訊錄黑名單         Cursor c1 = db.rawQuery(                    "select * from rcontact where verifyFlag =0 and type not in (2,4,8,9,33,35,256,258,512,2051,32768,32770,32776,33024,65536,65792,98304) and username not like "%@app" and username not like "%@qqim" and username not like "%@chatroom" and encryptUsername!=""",                    null);         while (c1.moveToNext())         {             String userName = c1.getString(c1.getColumnIndex("username"));             String alias = c1.getString(c1.getColumnIndex("alias"));             String nickName = c1.getString(c1.getColumnIndex("nickname"));             int type = c1.getInt(c1.getColumnIndex("type"));             contacts.add(new Contact(userName, alias, nickName));          }          Log.d("xag", "微信通訊錄中,聯絡人數目:" + contacts.size() + "個");          for (int i = 0; i < contacts.size(); i++)          {             Log.d("xag", contacts.get(i).getNickName());          }          c1.close();          db.close();    } catch (Exception e)    {          Log.e("xag", "讀取資料庫資訊失敗" + e.toString());          Toast.makeText(this, "讀取微信通訊錄失敗!", Toast.LENGTH_SHORT).show();    }    Toast.makeText(this, "讀取微信通訊錄成功!", Toast.LENGTH_SHORT).show();}

需要注意的是,資料庫中 rcontact 表的資料比較雜亂,除了正常的好友資料,黑名單好友、已刪除好友、公眾號、微信群等資料也包含在內,需要我們通過 type 和 verifyFlag 欄位進行篩選。

為了便於 Python 操作,最後將查詢的好友資料寫入到 csv 檔案中。

/*** * 寫入資料到csv中 * @param output_path * @param contacts */public static void writeCsvFile(String output_path, List<Contact> contacts){    try    {        File file = new File(output_path);        //刪除之前儲存的檔案        if (file.exists())        {             file.delete();        }        BufferedWriter bw = new BufferedWriter(new FileWriter(file, true));        // 新增頭部名稱        bw.write("userName" + "," + "alias" + "," + "nickName");        bw.newLine();        for (int i = 0; i < contacts.size(); i++)        {            bw.write(contacts.get(i).getUserName() + "," + contacts.get(i).getAlias() + "," + contacts.get(i).getNickName());            bw.newLine();        }        bw.close();     } catch (IOException e)     {         e.printStackTrace();     }}

第 2 步,我們需要模擬給好友轉賬,來判斷這個好友關係是否正常。

首先,我們需要初始化 Airtest,然後利用 adb 把第 1 步生成的資料從手機裡匯出到本地。

def __init_airtest(self):        """        初始化Airtest        :return:        """        device_1 = Android('822QEDTL225T7')        # device_1 = Android('emulator-5554')        connect_device("android:///")        self.poco = AndroidUiautomationPoco(device_1, screenshot_each_action=False)        auto_setup(__file__)def export_wx_db_from_phone(target_path):    """    從手機中匯出通訊錄資料    :param target_path:    :return:    """    # 微信通訊錄資料    wx_db_source_path = "/data/data/com.xingag.crack_wx/wx_data.csv"    # 匯出到本地    os.popen('adb pull %s %s' % (wx_db_source_path, target_path))

然後就是一系列自動化操作。

def __to_friend_chat_page(self, weixin_id):        """        點選到一個好友的聊天介面        :param weixin_id:        :param weixin_name:        :return:        """        # 1、點選搜尋        element_search = self.__wait_for_element_exists(self.id_search)        element_search.click()        print('點選搜尋')        # 2、搜尋框        element_search_input = self.__wait_for_element_exists(self.id_search_input)        element_search_input.set_text(weixin_id)        # 3、搜尋列表        element_search_result_list = self.__wait_for_element_exists(self.id_search_result_list)        # 3.1 是否存在對應的聯絡人,如果存在就在第一個子View佈局下        # 注意:可能出現最常用的聊天列表,這裡需要進行判斷        index_tips = 0        for index, element_search_result in enumerate(element_search_result_list.children()):            # 聯絡人的Tips            # if element_search_result_list.children()[0].offspring(self.id_contact_tips).exists():            if element_search_result.offspring(text=self.text_contact_tips).exists():                index_tips = index                break        # 4、點選第一個聯絡人進入聊天介面        element_search_result_list.children()[index_tips + 1].click()

接著嘗試著給對方轉賬,如果好友關係正常,就會跳出一個支付頁面讓輸入密碼。

def __judge_is_friend(self, weixin_id, weixin_name):        """        判斷是不是微信好友        :param weixin_id: 微訊號        :return:        """        # 嘗試給好友轉賬,設定一個小額度,以防止刷臉直接支付了        # 如果對方是你的好友,接下來會讓你輸入密碼,關掉頁面就行了        # 如果對方不是你的好友,會提示不是你的好友,不能繼續操作了        # 5、點選好友介面的+按鈕        self.poco(self.id_chat_more_button).click()        # 6、點選轉賬按鈕        self.poco(self.id_chat_more_container).offspring(text=self.text_chat_transfer_account_text).click()        # 7、輸入金額        self.poco(self.id_transfer_account_input).set_text(self.money)        # 8、點選轉賬按鈕        self.poco(self.id_transfer_account_container).offspring(text=self.text_chat_transfer_account_text).click()

如果是殭屍粉,應用會彈出一個警告對話方塊,提示你不是收款方好友,沒法完成轉賬的操作。

通過警告對話方塊是否存在,就可以判斷好友關係是否正常。非正常的好友關係,包含:殭屍粉、對方賬號異常等。

# 10.彈出警告對話方塊# 彈出好友關係不正常if element_transfer_account_result_button:     # 提示內容     ransfer_account_result_tips = self.poco(self.id_transfer_account_result_tips).get_text()     if self.text_friend_no_tips in transfer_account_result_tips:         print('注意!%s已經把你拉黑了!!!' % weixin_name)         self.friend_black_list.append({                    'id': weixin_id,                    'nickName': weixin_name                })         write_to_file(self.path_black_list, 'id:%s,nickName:%s' % (weixin_id, weixin_name))     elif self.text_friend_limit_tips in transfer_account_result_tips:         print('%s賬號收到限制!!!' % weixin_name)         write_to_file(self.path_account_limit, 'id:%s,nickName:%s' % (weixin_id, weixin_name))     elif self.text_friend_is_norm in transfer_account_result_tips:         print('%s好友關係不正常!!!' % weixin_name)         write_to_file(self.path_relationship_unnormal, 'id:%s,nickName:%s' % (weixin_id, weixin_name))     # 點選確認按鈕     element_transfer_account_result_button.click()     # 返回到主頁面     self.__back_to_home()else:     # 包含正常好友關係和對方賬號限制的情況     print('好友關係正常')     self.__back_to_home()

最後,模擬點選手機的返回鍵,一直回退到微信主介面。

def __back_to_home(self):        """        回退到主介面        :return:        """        print('準備回退到主介面')        home_tips = ['微信', '通訊錄', '發現', '我']        while True:            keyevent('BACK')            is_home = False            # 判斷是否到達首頁            if self.poco(text=home_tips[0]).exists() and self.poco(text=home_tips[1]).exists() and self.poco(                    text=home_tips[2]).exists() and self.poco(text=home_tips[3]).exists():                is_home = True            if is_home:                print('已經回到微信首頁~')                break

迴圈上面的操作,就可以判斷出哪些是殭屍粉,哪些好友的賬號被限制,哪些是正常的好友關係。

def del_friend_black(self, weixin_id):        """        刪除黑名單好友        :return:        """        # 到好友聊天介面        self.__to_friend_chat_page(weixin_id)        # 點選聊天介面右上角,進入到好友的詳細資訊介面        self.poco(self.id_person_msg_button).click()        # 點選好友頭像        self.poco(self.id_person_head_url).click()        # 點選個人名片的右上角,彈出好友操作選單        self.poco(self.id_person_manage_menu).click()        # 查詢刪除操作欄        # 注意:對於目前主流的手機,都需要滑動到最底部才能出現【刪除】這一操作欄        self.poco.swipe([0.5, 0.9], [0.5, 0.3], duration=0.2)        # 點選刪除,彈出刪除對話方塊        self.poco(self.id_person_del, text=self.text_person_del).click()        # 確定刪除好友【確定刪除】        # 介面會直接回到主介面        self.poco(self.id_person_del_sure, text=self.text_person_del).click()

4、結 果 結 論

然後執行 Python 程式會遍歷通訊錄好友資料,自動化去操作微信 App,接著將所有的殭屍粉寫入到本地檔案中,最後可以選擇將這些殭屍粉全部刪除掉。 最後注意:不管你是剛學Python還是想找python高薪工作,記住:專案開發經驗永遠是核心,如果你缺新專案練習或者沒有python入門到高階實戰視訊教程,可以關注我,後臺私信我 ‘py’ 自動獲取最新python教程資料!還有老司機解答哦!

最新評論
  • 整治雙十一購物亂象,國家再次出手!該跟這些套路說再見了
  • 民宿會員制已OUT,社交OTA能否幹翻攜程?