用Python全自動(dòng)下載抖音視頻!

/ 01 / Charles

用Charles來(lái)找視頻的API接口,具體操作和之前當(dāng)當(dāng)網(wǎng)那個(gè)案例一樣,不細(xì)說(shuō)。

這里通過(guò)滑動(dòng)抖音App,可以獲取到視頻的請(qǐng)求信息。

通過(guò)多次實(shí)驗(yàn),發(fā)現(xiàn)鏈接的后面是會(huì)不停的改變,只有鏈接的前頭始終不變,即「http://v1-dy」「http://v6-dy」「http://v9-dy」不變。

所以在寫腳本的時(shí)候,可以以這些信息做為鏈接開頭。

/ 02 / mitmproxy

利用mitmproxy中的mitmdump組件,對(duì)接Python腳本,用Python實(shí)現(xiàn)監(jiān)聽后的處理。

這里我只是利用腳本獲取鏈接,并沒(méi)有直接利用腳本下載視頻。

因?yàn)槲沂窃趍itmdump.exe文件所在的文件夾運(yùn)行腳本,腳本里導(dǎo)入不了requests模塊。

不想搞那些煩人的環(huán)境變量,所以只獲取鏈接。

然后再去下載視頻,視頻鏈接需要去重,可能會(huì)有重復(fù)的。

Python腳本如下。

def?response(flow):

urls = ['http://v1-dy',?'http://v3-dy',?'http://v6-dy',?'http://v9-dy']

# 對(duì)url進(jìn)行篩選,只選取視頻的url

for?url?in?urls:

if?url?in?flow.request.url:

print('\n\n抖音視頻\n\n')

with?open('douyin.csv',?'a+', encoding='utf-8-sig')?as?f:

f.write(flow.request.url +?'\n')

/ 03 / Appium


配置抖音的Appium參數(shù)。

點(diǎn)擊藍(lán)色按鈕,手機(jī)自動(dòng)啟動(dòng)抖音App!

接下來(lái)操作手機(jī),然后點(diǎn)擊Appium的刷新鍵,獲取元素定位代碼。

通過(guò)本次的實(shí)踐發(fā)現(xiàn)Appium有時(shí)并不能很好的獲取元素的定位,這可能就跟Web端的iframe頁(yè)面一樣。

所以針對(duì)找不到的元素,我直接對(duì)手機(jī)屏幕位置進(jìn)行點(diǎn)擊。

由于大家手機(jī)屏幕大小不同,這個(gè)參數(shù)肯定是會(huì)變化的,所以存在弊端,無(wú)法通用。

{? 左右滑動(dòng)切換圖片? }

大致操作如上圖。UP主的主頁(yè)圖漏了,請(qǐng)自行腦補(bǔ),Python代碼如下。

import?time

import?random

from?appium?import?webdriver

from?selenium.webdriver.common.by?import?By

from?selenium.webdriver.support.ui?import?WebDriverWait

from?appium.webdriver.common.touch_action?import?TouchAction

from?selenium.webdriver.support?import?expected_conditions?as?EC

def main():

# 設(shè)置驅(qū)動(dòng)配置

server =?'http://localhost:4723/wd/hub'

desired_caps = {

'platformName':?'Android',

'deviceName':?'STF_AL00',

'appPackage':?'com.ss.android.ugc.aweme',

'appActivity':?'.main.MainActivity',

# 關(guān)閉手機(jī)軟鍵盤

'unicodeKeyboard': True,

'resetKeyboard': True

}

driver = webdriver.Remote(server, desired_caps)

wait = WebDriverWait(driver,?60)

# 同意用戶隱私協(xié)議,點(diǎn)擊

button_1 = wait.until(EC.presence_of_element_located((By.ID,?'com.ss.android.ugc.aweme:id/q6')))

button_1.click()

# 禁止電話權(quán)限,點(diǎn)擊

button_2 = wait.until(EC.presence_of_element_located((By.ID,?'com.android.packageinstaller:id/permission_deny_button')))

button_2.click()

# 禁止位置權(quán)限,點(diǎn)擊

button_3 = wait.until(EC.presence_of_element_located((By.ID,?'com.android.packageinstaller:id/permission_deny_button')))

button_3.click()

time.sleep(2)

# 向上滑動(dòng),進(jìn)入抖音視頻播放頁(yè)面

TouchAction(driver).press(x=515, y=1200).move_to(x=515, y=1000).release().perform()

# 這里需要設(shè)置一個(gè)較長(zhǎng)時(shí)間的延遲,因?yàn)槎兑粲幸龑?dǎo)操作和提示,需等待片刻

time.sleep(20)

# 點(diǎn)擊抖音"喜歡"處,以此進(jìn)入登錄界面

TouchAction(driver).press(x=950, y=800).release().perform()

# 點(diǎn)擊密碼登錄

button_4 = wait.until(EC.presence_of_element_located((By.ID,?'com.ss.android.ugc.aweme:id/afg')))

button_4.click()

# 輸入賬號(hào)

button_5 = wait.until(EC.presence_of_element_located((By.ID,?'com.ss.android.ugc.aweme:id/ab_')))

button_5.send_keys('你的賬號(hào)')

# 輸入密碼

button_6 = wait.until(EC.presence_of_element_located((By.ID,?'com.ss.android.ugc.aweme:id/aes')))

button_6.send_keys('你的密碼')

time.sleep(2)

# 因?yàn)闀?huì)跳出軟鍵盤,會(huì)遮擋登錄按鈕,需點(diǎn)擊軟鍵盤取消

TouchAction(driver).press(x=980, y=1850).release().perform()

time.sleep(2)

# 點(diǎn)擊登錄按鈕

button_7 = wait.until(EC.presence_of_element_located((By.ID,?'com.ss.android.ugc.aweme:id/abb')))

button_7.click()

time.sleep(2)

# 登錄成功,進(jìn)入抖音視頻界面,點(diǎn)擊下方標(biāo)題欄 "我"

TouchAction(driver).press(x=990, y=1850).release().perform()

# 進(jìn)入個(gè)人主頁(yè),點(diǎn)擊關(guān)注處

button_8 = wait.until(EC.presence_of_element_located((By.ID,?'com.ss.android.ugc.aweme:id/a_7')))

button_8.click()

# 進(jìn)入關(guān)注欄,點(diǎn)擊第二個(gè)關(guān)注

button_9 = wait.until(EC.presence_of_element_located((By.XPATH,?' ? ?/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.LinearLayout/android.support.v7.widget.RecyclerView/android.widget.RelativeLayout[2]/android.widget.RelativeLayout[1]')))

button_9.click()

# 進(jìn)入U(xiǎn)P主主頁(yè),點(diǎn)擊第一個(gè)視頻

button_10 = wait.until(EC.presence_of_element_located((By.ID,?'com.ss.android.ugc.aweme:id/aqm')))

button_10.click()

# 不斷下滑頁(yè)面,直到底部

while?True:

TouchAction(driver).press(x=515, y=1247).move_to(x=515, y=1026).release().perform()

time.sleep(float(random.randint(5,?10)))

if?__name__ ==?'__main__':

main()

下載視頻代碼,需要對(duì)視頻鏈接去重。

import?pandas?as?pd

import?requests

import?os

num =?0

dom = []

folder_path =?"F:/video/"

os.makedirs(folder_path)

df = pd.read_csv('douyin.csv', header=None, names=["url"])

# 對(duì)鏈接去重及去除剛進(jìn)入抖音獲取的視頻鏈接

for?i?in?df['url'][2:]:

if?i?not?in?dom:

dom.append(i)

# 下載視頻

for?j?in?dom:

url = j

num +=?1

response = requests.get(url, stream=True)

filename = str(num) +?'.mp4'

with?open('F:\\video\\'?+ filename,?'ab+')?as?f:

f.write(response.content)

f.flush()

print(filename +?'下載完成')

最后成功獲取小姐姐們的全部視頻...

要是曾經(jīng)在廠子里的我,那時(shí)會(huì)這騷操作該多好,哈哈。

其實(shí)我想的更多,多數(shù)妹子都挺喜歡拍抖音,不過(guò)她們應(yīng)該不會(huì)下載這種操作滴。

那么小老弟們的機(jī)會(huì)就來(lái)了,下載下來(lái)喜歡的妹子的抖音視頻。

然后剪輯出一個(gè)「最美瞬間」系列的視頻,機(jī)會(huì)不就來(lái)了嘛...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容