點擊“ 開發者技術前線 ”,選擇“星標”
在看|星標|留言,? 真愛
1
目 標 場 景
相信大家平時刷抖音短視頻的時候,看到顏值高的小姐姐,都有隨手點贊關注的習慣。
如果一條條去刷確實很耗時間,如果 Python 能幫忙篩選出顏值高的小姐姐那就省了很多事。
本篇文章是借助 「 百度人臉識別 」API ,幫我們識別出抖音上顏值高的小姐姐,然后下載到手機相冊中。
2
準 備 工 作
首先,項目需要對頁面元素進行一些精準的操作,需要提前準備一部 Android 設備,激活開發者選項,并在開發者選項中打開 「 USB 調試和指針位置 」兩處設置 。
為了確保 adb 命令能正常使用,需要提前配置好 adb 開發環境。
頁面元素中的部分元素沒法利用 name 等常用屬性獲取到,可能需要獲取到完整的 「 UI 樹 」 ,再利用 Airtest 判斷是否存在某個 UI 元素。
# 安裝依賴
pip3?install?pocoui
另外,項 目中會對視頻進行人臉識別,獲取到出現的所有人臉,再 進行性別識別及顏值判斷。
這里需要進行百度云后臺, 注冊一個人臉識別的應用,獲取到一組? 「 API Key 和 Secret Key 」值 。
https://console.bce.baidu.com
然后利用官網提供的 API 文檔即可獲取到 「 access token 」,由于? ak 的有效期為一個月,所以只需要初始化一次,后面就可以利用人臉識別接口進行正常的識別了。
appid?=?'你注冊應用的appid'api_key?=?'你注冊應用的ak'secret_key?=?'你注冊應用的sk'def?get_access_token():????"""?????其關access_token有效期一般有一個月????"""????#?此變量賦值成自己API?Key的值????client_id?=?api_key??????#?此變量賦值成自己Secret?Key的值????client_secret?=?secret_key??????auth_url?=?'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='?+?client_id?+?'&client_secret='?+?client_secret????header_dict?=?{'User-Agent':?'Mozilla/5.0?(Windows?NT?6.1;?Trident/7.0;?rv:11.0)?like?Gecko',???????????????????"Content-Type":?"application/json"}????#?請求獲取到token的接口????response_at?=?requests.get(auth_url,?headers=header_dict)????json_result?=?json.loads(response_at.text)????access_token?=?json_result['access_token']????return?access_token
api_key?=?
'你注冊應用的ak'
secret_key?=?
'你注冊應用的sk'
def
?
get_access_token
()
:
????
"""
?????其關access_token有效期一般有一個月
????"""
????
#?此變量賦值成自己API?Key的值
????client_id?=?api_key??
????
#?此變量賦值成自己Secret?Key的值
????client_secret?=?secret_key??
????auth_url?=?
'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='
?+?client_id?+?
'&client_secret='
?+?client_secret
????header_dict?=?{
'User-Agent'
:?
'Mozilla/5.0?(Windows?NT?6.1;?Trident/7.0;?rv:11.0)?like?Gecko'
,
???????????????????
"Content-Type"
:?
"application/json"
}
????
#?請求獲取到token的接口
????response_at?=?requests.get(auth_url,?headers=header_dict)
????json_result?=?json.loads(response_at.text)
????access_token?=?json_result[
'access_token'
]
????
return
?access_token
3
編? 寫? 腳? 本
在上面已經配置好了 adb 環境的情況下,可以直接借助 python 中的 os 模塊執行 adb 命令打開抖音 App。
#?抖音App的應用包名和初始Activitypackage_name?=?'com.ss.android.ugc.aweme'activity_name?=?'com.ss.android.ugc.aweme.splash.SplashActivity'
def?start_my_app(package_name,?activity_name):????"""????打開應用????adb?shell?am?start?-n?com.tencent.mm/.ui.LauncherUI????:param?package_name:????:return:????"""????os.popen('adb?shell?am?start?-n?%s/%s'?%?(package_name,?activity_name))
????
"""
????打開應用
????adb?shell?am?start?-n?com.tencent.mm/.ui.LauncherUI
????:param?package_name:
????:return:
????"""
????os.popen(
'adb?shell?am?start?-n?%s/%s'
?%?(package_name,?activity_name))
接著,我們需要截取當前播放視頻的截圖到本地。
需要注意的是,抖音視頻播放界面包含視頻創作者頭像、BGM 創作者頭像等一些雜亂的元素,可能對人臉識別的結果產生一些誤差,所以需要對屏幕截圖之后的圖像進行 「 二次裁剪 」處理 。
def?get_screen_shot_part_img(image_name):????"""????獲取手機截圖的部分內容????:return:????"""????#?截圖????os.system("adb?shell?/system/bin/screencap?-p?/sdcard/screenshot.jpg")????os.system("adb?pull?/sdcard/screenshot.jpg?%s"?%?image_name)????#?打開圖片????img?=?Image.open(image_name).convert('RGB')????#?圖片的原寬、高(1080*2160)????w,?h?=?img.size????#?截取部分,去掉其頭像、其他內容雜亂元素????img?=?img.crop((0,?0,?900,?1500))????img.thumbnail((int(w?/?1.5),?int(h?/?1.5)))????#?保存到本地????img.save(image_name)????return?image_name
????
"""
????獲取手機截圖的部分內容
????:return:
????"""
????
#?截圖
????os.system(
"adb?shell?/system/bin/screencap?-p?/sdcard/screenshot.jpg"
)
????os.system(
"adb?pull?/sdcard/screenshot.jpg?%s"
?%?image_name)
????
#?打開圖片
????img?=?Image.open(image_name).convert(
'RGB'
)
????
#?圖片的原寬、高(1080*2160)
????w,?h?=?img.size
????
#?截取部分,去掉其頭像、其他內容雜亂元素
????img?=?img.crop((
0
,?
0
,?
900
,?
1500
))
????img.thumbnail((int(w?/?
1.5
),?int(h?/?
1.5
)))
????
#?保存到本地
????img.save(image_name)
????
return
?image_name
現在可以使用百度提供的 API 獲取到上面截圖的人臉列表。
def?parse_face_pic(pic_url,?pic_type,?access_token):????"""????人臉識別????5秒之內????:param?pic_url:????:param?pic_type:????:param?access_token:????:return:????"""????url_fi?=?'https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token='?+?access_token????#?調用identify_faces,獲取人臉列表????json_faces?=?identify_faces(pic_url,?pic_type,?url_fi)????if?not?json_faces:????????print('未識別到人臉')????????return?None????else:????????#?返回所有的人臉????????return?json_faces
????
"""
????人臉識別
????5秒之內
????:param?pic_url:
????:param?pic_type:
????:param?access_token:
????:return:
????"""
????url_fi?=?
'https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token='
?+?access_token
????
#?調用identify_faces,獲取人臉列表
????json_faces?=?identify_faces(pic_url,?pic_type,?url_fi)
????
if
?
not
?json_faces:
????????print(
'未識別到人臉'
)
????????
return
?
None
????
else
:
????????
#?返回所有的人臉
????????
return
?json_faces
從上述的人臉列表中篩選出性別為女,年齡為 18-30 歲之間,顏值超過 70 的小姐姐。
def?analysis_face(face_list):????"""????分析人臉,判斷顏值是否達標????18-30之間,女,顏值大于80????:param?face_list:識別的臉的列表????:return:????"""????#?是否能找到高顏值的美女????find_belle?=?False????if?face_list:????????print('一共識別到%d張人臉,下面開始識別是否有美女~'?%?len(face_list))????????for?face?in?face_list:????????????#?判斷是男、女????????????if?face['gender']['type']?==?'female':????????????????age?=?face['age']????????????????beauty?=?face['beauty']????????????????if?18?<=?age?<=?30?and?beauty?>=?70:????????????????????print('顏值為:%d,及格,滿足條件!'?%?beauty)????????????????????find_belle?=?True????????????????????break????????????????else:????????????????????print('顏值為:%d,不及格,繼續~'?%?beauty)????????????????????continue????????????else:????????????????print('性別為男,繼續~')????????????????continue????else:????????print('圖片中沒有發現人臉.')????return?find_belle
????
"""
????分析人臉,判斷顏值是否達標
????18-30之間,女,顏值大于80
????:param?face_list:識別的臉的列表
????:return:
????"""
????
#?是否能找到高顏值的美女
????find_belle?=?
False
????
if
?face_list:
????????print(
'一共識別到%d張人臉,下面開始識別是否有美女~'
?%?len(face_list))
????????
for
?face?
in
?face_list:
????????????
#?判斷是男、女
????????????
if
?face[
'gender'
][
'type'
]?==?
'female'
:
????????????????age?=?face[
'age'
]
????????????????beauty?=?face[
'beauty'
]
????????????????
if
?
18
?<=?age?<=?
30
?
and
?beauty?>=?7
0
:
????????????????????print(
'顏值為:%d,及格,滿足條件!'
?%?beauty)
????????????????????find_belle?=?
True
????????????????????
break
????????????????
else
:
????????????????????print(
'顏值為:%d,不及格,繼續~'
?%?beauty)
????????????????????
continue
????????????
else
:
????????????????print(
'性別為男,繼續~'
)
????????????????
continue
????
else
:
????????print(
'圖片中沒有發現人臉.'
)
????
return
?find_belle
由于視頻是連續播放的,很難通過截取視頻某一幀,判斷視頻有出現顏值高的小姐姐。
另外,大部分短視頻播放時長為 「 10s+ 」 ,這里需要對每一個視頻多次截圖去做人臉識別 ,直到識別到顏值高的小姐姐。
# 一條視頻最長的識別時間
RECOGNITE_TOTAL_TIME = 10?
#?識別次數recognite_count?=?1#?對當前視頻截圖去人臉識別while?True:??#?獲取截圖??print('開始第%d次截圖'?%?recognite_count)??#?截取屏幕有用的區域,過濾視頻作者的頭像、BGM作者的頭像??screen_name?=?get_screen_shot_part_img('images/temp%d.jpg'?%?recognite_count)??#?人臉識別??recognite_result?=?analysis_face(parse_face_pic(screen_name,?TYPE_IMAGE_LOCAL,?access_token))??recognite_count?+=?1??#?第n次識別結束后的時間??recognite_time_end?=?datetime.now()??#?這一條視頻出現了顏值高的小姐姐??if?recognite_result:?????????pass??else:?????????print('超時!!!這是一條沒有吸引力的視頻!')?????????#?跳出里層循環?????????break
recognite_count?=?
1
#?對當前視頻截圖去人臉識別
while
?
True
:
??
#?獲取截圖
??print(
'開始第%d次截圖'
?%?recognite_count)
??
#?截取屏幕有用的區域,過濾視頻作者的頭像、BGM作者的頭像
??screen_name?=?get_screen_shot_part_img(
'images/temp%d.jpg'
?%?recognite_count)
??
#?人臉識別
??recognite_result?=?analysis_face(parse_face_pic(screen_name,?TYPE_IMAGE_LOCAL,?access_token))
??recognite_count?+=?
1
??
#?第n次識別結束后的時間
??recognite_time_end?=?datetime.now()
??
#?這一條視頻出現了顏值高的小姐姐
??
if
?recognite_result:
?????????
pass
??
else
:
?????????print(
'超時!!!這是一條沒有吸引力的視頻!'
)
?????????
#?跳出里層循環
?????????
break
一旦當前播放的視頻識別出有顏值高的小姐姐,就需要模擬保存視頻到本地的操作。
獲取
「
分享
」
和
「
保存本地
」兩個按鈕的坐標位置,依次利用 adb 執行點擊操作即可下載視頻到本地。
def?save_video_met():????"""????:return:????"""????#?分享????os.system("adb?shell?input?tap?1000?1500")????time.sleep(0.05)????#?保存到本地????os.system("adb?shell?input?tap?350?1700")
????
"""
????:return:
????"""
????
#?分享
????os.system(
"adb?shell?input?tap?1000?1500"
)
????time.sleep(
0.05
)
????
#?保存到本地
????os.system(
"adb?shell?input?tap?350?1700"
)
另外,由于下載視頻的過程是一個耗時操作,在下載進度對話框還未消失之前,需要做一個 「 模擬等待 」的 操作。
def?wait_for_download_finished(poco):????"""????從點擊下載,到下載完全????:return:????"""????element?=?Element()????while?True:????????#?由于是對話框,不能利用Element類來判斷是否存在某個元素來準確處理????????#?element_result?=?element.findElementByName('正在保存到本地')????????#?當前頁面UI樹元素信息????????#?注意:保存的時候可能會獲取元素異常,這里需要拋出,并終止循環????????#?com.netease.open.libpoco.sdk.exceptions.NodeHasBeenRemovedException:?Node?was?no?longer?alive?when?query?attribute?"visible".?Please?re-select.????????try:????????????ui_tree_content?=?json.dumps(poco.agent.hierarchy.dump(),?indent=4).encode('utf-8').decode('unicode_escape')????????except?Exception?as?e:????????????print(e)????????????print('異常,按下載處理~')????????????break????????if?'正在保存到本地'?in?ui_tree_content:????????????print('還在下載中~')????????????time.sleep(0.5)????????????continue????????else:????????????print('下載完成~')????????????break
????
"""
????從點擊下載,到下載完全
????:return:
????"""
????element?=?Element()
????
while
?
True
:
????????
#?由于是對話框,不能利用Element類來判斷是否存在某個元素來準確處理
????????
#?element_result?=?element.findElementByName('正在保存到本地')
????????
#?當前頁面UI樹元素信息
????????
#?注意:保存的時候可能會獲取元素異常,這里需要拋出,并終止循環
????????
#?com.netease.open.libpoco.sdk.exceptions.NodeHasBeenRemovedException:?Node?was?no?longer?alive?when?query?attribute?"visible".?Please?re-select.
????????
try
:
????????????ui_tree_content?=?json.dumps(poco.agent.hierarchy.dump(),?indent=
4
).encode(
'utf-8'
).decode(
'unicode_escape'
)
????????
except
?Exception?
as
?e:
????????????print(e)
????????????print(
'異常,按下載處理~'
)
????????????
break
????????
if
?
'正在保存到本地'
?
in
?ui_tree_content:
????????????print(
'還在下載中~'
)
????????????time.sleep(
0.5
)
????????????
continue
????????
else
:
????????????print(
'下載完成~'
)
????????????
break
在視頻保存到本地之后,就可以模擬向上滑動的操作,跳到播放 「 下一條視頻 」 。
循環上面的操作,即可篩選出所有顏值高的小姐姐,并保存到本地。
def?play_next_video():????"""????下一個視頻????從下往上滑動????:return:????"""????os.system("adb?shell?input?swipe?540?1300?540?500?100")
????
"""
????下一個視頻
????從下往上滑動
????:return:
????"""
????os.system(
"adb?shell?input?swipe?540?1300?540?500?100"
)
在腳本一條條刷視頻的過程中,可能會遇到一下廣告,我們需要對這類視頻進行過濾。
def?is_a_ad():????"""????判斷的當前頁面上是否是一條廣告????:return:????"""????element?=?Element()????ad_tips?=?['去玩一下',?'去體驗',?'立即下載']????find_result?=?False????for?ad_tip?in?ad_tips:????????try:????????????element_result?=?element.findElementByName(ad_tip)????????????#?是一條廣告,直接跳出????????????find_result?=?True????????????break????????except?Exception?as?e:????????????find_result?=?False????return?find_result
????
"""
????判斷的當前頁面上是否是一條廣告
????:return:
????"""
????element?=?Element()
????ad_tips?=?[
'去玩一下'
,?
'去體驗'
,?
'立即下載'
]
????find_result?=?
False
????
for
?ad_tip?
in
?ad_tips:
????????
try
:
????????????element_result?=?element.findElementByName(ad_tip)
????????????
#?是一條廣告,直接跳出
????????????find_result?=?
True
????????????
break
????????
except
?Exception?
as
?e:
????????????find_result?=?
False
????
return
?find_result
4
結 果 結 論
運行上面的腳本,會自動打開抖音,對每一條小視頻多次進行人臉識別,直到識別到顏值高的小姐姐,保存視頻到本地,然后繼續刷下一條短視頻。
我已經將全部源碼 上傳到后臺上,公眾號回復「? 好看的小姐姐? 」即可獲得。
后臺回復?
交流群
,進入公眾號的交流群,?
作者 :
新
安果,喜歡就可以關注。
--end--
歷史推薦選擇” 開發者技術前線 ?“星標 ,內容一觸即達。
開發者技術前線 ?匯集技術前線快訊和關注行業趨勢,大廠干貨,是開發者經歷和成長的優秀指南。
為什么 Python 4.0 不會像 3.0 一樣?
Java 12 / JDK 12 正式發布,看看有哪些新特性
美團基于跨平臺 Flutter 的動態化平臺建設

點個在看,解鎖更多驚喜
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
