微信群牛皮癬,指的是在微信群裡面惡心群發小廣告的用戶,是微信群主最痛恨的一波人。如果熟悉早起的讀者可以知道我有一個技術交流群,但是自從建群以來就飽受小廣告的困擾。他們僞裝成正常人的樣子混進群然後不停的發送廣告轟炸,嚴重的打亂了群内的技術交流氣氛
或者是一聲不吭的去騷擾每一個群成員
雖然不清楚是什麼能夠驅使他們這樣不折不扣的努力成為最強微信群牛皮癬(可能是鈔能力),但是在太多次的騷擾之後,我決定拿起Python消滅這些小廣告。
第一回合其實實現思路很簡單,總共分兩步
但是這兩步,每一步都不簡單,先來說說第一步如何準确的識别這些用戶,網上沒有數據也沒有一個好的鑒别标準,隻能用我的大腦完成特征識别。經過這幾個月,近百份發廣告用戶的樣本訓練,基本可以判斷一個非正常用戶至少滿足下面幾條中的三條以上:
并且根據曆史數據,符合1、3條的用戶有極大概率為小廣告愛好者,那麼接下來要做的就是用Python寫代碼找出微信裡面的這些人。在總結出這一規律後很樂觀的認為實現這一需求并不困難,因為我在幾年前就曾拿過Python研究微信好友,不論是wxpy還是itchat操作起來應該都不複雜,但是事實卻證明我還是太年輕了
不知從何時起,雖然這些庫還能使用但是微信基本已經禁止了大部分人的網頁版微信登陸權限,因此當我使用多個微信号分别掃完登陸微信的二維碼之後,無一例外的提示我
<error><ret>1203</ret><message>
為了你的帳号安全,此微信号已不允許登錄網頁微信。
你可以使用Windows微信或Mac微信在電腦端登錄。
</message></error>
這就讓人頭疼了,總不能手動的去一個一個check我的幾千個微信好友吧,于是我開始思考是否有其他的解決辦法。
第二回合如果你經常寫Python爬蟲,那麼你會知道在有些情況下,與其使用Requests對付一些惡心的反爬措施,不如Selenium操作起來方便。所以在發現想使用基于微信API的思路失效後,我将目光轉向了相對笨一點的方法————pynput
pynput是一款使用Python來控制和監控電腦鼠标、鍵盤的第三方庫,說到這裡你大概明白我想怎麼做了,直接用API取數據搞不定,那麼我就像Selenium一樣,模拟點擊一個一個好友來實現我想要的操作。
下面簡單說一下這個庫,因為沒有太多依賴庫所以安裝起來很簡單,直接pip install pynput即可,使用起來也很簡單,對于鼠标操作隻依賴坐标,看個demo
就像上面GIF演示的一樣,先導入pynput并實例一個鼠标控制器,接着将微信在狀态欄的位置提交給mouse.position,這樣鼠标就會移動到該位置,再使用mouse.press來模拟鼠标點擊即可自動打開微信。那麼問題來了,如何獲得我想要的位置的坐标?
pynput除了使可以使用Controller來控制鼠标,也可以監控鼠标,比如使用下面的代碼就可以記錄下程序啟動後鼠标的每一個點擊操作所在的位置
frompynputimportmouse
defon_move(x,y):
print('鼠标移動至{0}'.format(
(x,y)))
defon_click(x,y,button,pressed):
print('{0}在坐标{1}'.format('鼠标點擊'ifpressedelse'鼠标釋放',(x,y)))
ifnotpressed:
returnFalse
whileTrue:
withmouse.Listener(on_move=on_move,on_click=on_click)aslistener:
listener.join()
那麼接下來的任務就簡單了,我們隻需要保持微信窗口不移動,在記錄下每一個關鍵位置的坐标(微信圖标位置,群聊窗口位置,單個群成員頭像位置)之後,比如我們想對上面說的第一條規則進行判斷即獲取每一個群成員微信号是否設置,就可以按照模拟以下操作實現:
在上面的過程中,值得說的是最後一步,複制我們可以使用pynput中的鍵盤控制器,在雙擊選中對應微信号之後通過下面的代碼實現模拟鍵盤輸入Command C完成複制操作
frompynput.keyboardimportKey
frompynput.keyboardimportControllerasController1
keyboard=Controller1()
withkeyboard.pressed(Key.cmd):
keyboard.press('c')
keyboard.release('c')
但是粘貼則不需要使用pynput通過模拟command c來粘貼到另一個編輯中複雜過程,我們可以使用第三方庫pyperclip,直接通過下面兩行代碼即可将複制好的文字轉為字符串
importpyperclip
pyperclip.paste()
在将群成員的微信号轉換為字符串後,不論我們是通過判斷字符串的長度還是用正則表達式或者是其他的方法都可以輕松的判斷該成員的微信号是否為初始微信号,實現規則1的判斷,下面的代碼與動态圖就是一次**完整的過程
frompynput.mouseimportButton,Controller
importtime
frompynput.keyboardimportKey
frompynput.keyboardimportControllerasController1
importpyperclip
mouse=Controller()
#點擊微信
mouse.position=(1046.14453125,4.546875)
time.sleep(2)
mouse.press(Button.left)
mouse.release(Button.left)
#點擊頭像
mouse.position=(1194.140625,441.05859375)
time.sleep(1)
mouse.press(Button.left)
mouse.release(Button.left)
#點擊選中文本
mouse.position=(965.60546875,284.0390625)
time.sleep(1)
mouse.click(Button.left,2)
keyboard=Controller1()
withkeyboard.pressed(Key.cmd):
keyboard.press('c')
keyboard.release('c')
time.sleep(1)
wechatid=pyperclip.paste()
print(f"微信号{wechatid}疑似廣告号"iflen(wechatid)>20elsef"微信号{wechatid}不是廣告号")
可以看到成功将早小起的微信從廣告号中排除
那麼接下來隻需要記錄下每兩個群成員之間間隔的坐标距離,之後循環去模拟滾動或者下拉來實現上述過程,就可以将群裡所有成員的微信号根據規則1進行判斷,找到異常的那些成員單獨進行判斷。
可以看到最終是找到了6個疑似廣告号的微信,接下來通過其他規則的手動判斷最終将兩個用戶判定為廣告高風險用戶并移除。
寫在最後通過上面的操作,雖然成功的踢出了兩個疑似廣告号,但是依舊很難去判斷是否真的踢對了人,如果踢錯了,那麼則粉絲-1,同時也可以發現想用Python準确找到群裡的牛皮癬還是非常困難的,使用pynput最多可以完成微信号及頭像(使用識圖API)的判斷,但是更多的信息卻很難提取挖掘。
同時pynput有着和selenium同樣的缺點,那就是由于模拟真人操作而導緻的速度慢,并且它的定位方式僅支持坐标,所以還需要保證在操作的過程中微信窗口不可以被移動,否則之前記錄的元素将全部失效(建議開發者可以支持更多的定位方式)
如果你有好的思路可以在留言區和我交流,如果你想看更詳細的pynput講解,不要忘記給個三連。如果你對本文的代碼感興趣,可以在公衆号早起Python中找到!
今天的文章就到這裡,為了維護良好的群内交流環境,對抗小廣告的路還在繼續,拜拜~
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!