python爬app视频_用Python爬抖音APP短视频

和大家一起来爬取当下大火的APP--抖音,批量下载一个用户发布的所有视频。各位也应该知道,抖音只有移动端,官网打开除了给你个APP下载二维码啥也没有,所以相比爬PC网站,还是遇到了更多的问题,也花了更多的时间,不过好在基本实现了,除了一点咱在后面说。

思路梳理

其实如果看了其他博主爬抖音的教程就发现,大部分都是通过fildder手机抓包来获取接口地址等信息,其实不用那么麻烦,我们通过分享选择链接形式就可以获取到信息:

然后电脑访问这个链接,就可以打开页面了,不过很快我们就会发现一个问题,电脑访问这个地址发布视频是空的:

谷歌Chrome浏览器有一个模拟手机访问的功能,我们选在iPhone X模式来访问页面,果然看到发布的视频了:

我们接下来看下后台请求,不多,很快就找到我们需要的视频信息了,也能直接打开观看视频,到这感觉已经成功了一大半了:

但很快我们有发现了新问题,可以看到莉哥总共发布了93个作品,但我们实际获取到但链接只有19个。其实我们用过抖音,包括微博这些应用的都知道,很多信息他们不是一次加载完的,当你拖动页面的时候才会继续加载。所以我们尝试上拉页面,就会发现后台又多了一个请求,返回了新加载的视频信息。

https://www.amemv.com/aweme/v1/aweme/post/?user_id=57720812347&count=21&max_cursor=0&aid=1128&_signature=KRLTTRAdclaWZCKrElzZVykS01&dytk=4830f6e279a5f53872aab9e9dc112d33 https://www.amemv.com/aweme/v1/aweme/post/?user_id=57720812347&count=21&max_cursor=1530363175000&aid=1128&_signature=KRLTTRAdclaWZCKrElzZVykS01&dytk=4830f6e279a5f53872aab9e9dc112d33

两个地址除了max_cursor其他都一样,其实就是上一条返回的json数据中的max_cursor就是下个链接中的max_cursor,然后has_more等于1的时候表示还未全部加载,这样逻辑就清楚了,我们只要先判断has_more是否等于1,等于1的时候我们将max_cursor的值传入下一个链接继续访问获取视频地址,直到has_more等于0为止。

这样所有视频地址都有了,就开始下载吧!!

代码部分

fromseleniumimportwebdriver

frombs4importBeautifulSoup

importjson

importrequests

importsys

importtime

importos

importuuid

fromcontextlibimportclosing

fromrequests.packages.urllib3.exceptionsimportInsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

classdouyin_spider(object):

"""docstringfordouyin_spider"""

def__init__(self,user_id,_signature,dytk):

print'*******DouYin_spider******'

print'Author:Awesome_Tang'

print'Date:2018-07-29'

print'Version:Python2.7'

print'**************************'

print''

self.userid=user_id

self.headers={'User-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/65.0.3325.146Safari/537.36'}

mobile_emulation={'deviceName':'iPhoneX'}

#chrome浏览器模拟iPhoneX进行页面访问

options=webdriver.ChromeOptions()

options.add_experimental_option("mobileEmulation",mobile_emulation)

self.browser=webdriver.Chrome(chrome_options=options)

self._signature=_signature

self.dytk=dytk

self.url='https://www.amemv.com/aweme/v1/aweme/post/?user_id=%s&count=32&max_cursor=0&aid=1128&_signature=%s&dytk=%s'%(self.userid,self._signature,self.dytk)

defhandle_url(self):

url_list=[self.url,]

self.browser.get(self.url)

web_data=self.browser.page_source

soup=BeautifulSoup(web_data,'lxml')

web_data=soup.pre.string

web_data=json.loads(str(web_data))

ifweb_data['status_code']==0:

whileweb_data['has_more']==1:

#最大加载32条视频信息,has_more等于1表示还未全部加载完

max_cursor=web_data['max_cursor']

#获取时间戳

url='https://www.amemv.com/aweme/v1/aweme/post/?user_id=%s&count=32&max_cursor=%s&aid=1128&_signature=%s&dytk=%s'%(self.userid,max_cursor,self._signature,self.dytk)

url_list.append(url)

self.browser.get(url)

web_data=self.browser.page_source

soup=BeautifulSoup(web_data,'lxml')

web_data=soup.pre.string

web_data=json.loads(str(web_data))

else:

max_cursor=web_data['max_cursor']

#获取时间戳

url='https://www.amemv.com/aweme/v1/aweme/post/?user_id=%s&count=32&max_cursor=%s&aid=1128&_signature=%s&dytk=%s'%(self.userid,max_cursor,self._signature,self.dytk)

url_list.append(url)

else:

url_list=[]

returnurl_list

defget_download_url(self,url_list):

download_url=[]

title_list=[]

iflen(url_list)>0:

forurlinurl_list:

self.browser.get(url)

web_data=self.browser.page_source

soup=BeautifulSoup(web_data,'lxml')

web_data=soup.pre.string

web_data=json.loads(str(web_data))

ifweb_data['status_code']==0:

foriinrange(len(web_data['aweme_list'])):

download_url.append(web_data['aweme_list'][i]['video']['play_addr']['url_list'][0])

title_list.append(web_data['aweme_list'][i]['share_info']['share_desc'].encode('utf-8'))

returndownload_url,title_list

defvideodownloader(self,url,title):

size=0

path=title+'.mp4'

withclosing(requests.get(url,headers=self.headers,stream=True,verify=False))asresponse:

chunk_size=1024

content_size=int(response.headers['content-length'])

ifresponse.status_code==200:

print'%sisdownloading...'%title

sys.stdout.write('[FileSize]:%0.2fMB\n'%(content_size/chunk_size/1024))

withopen(path,'wb')asf:

fordatainresponse.iter_content(chunk_size=chunk_size):

f.write(data)

size+=len(data)

f.flush()

sys.stdout.write('[Progress]:%0.2f%%'%float(size/content_size*100)+'\r')

sys.stdout.flush()

else:

printresponse.status_code

defrun(self):

url='https://www.amemv.com/aweme/v1/aweme/post/?user_id=%s&count=32&max_cursor=0&aid=1128&_signature=%s&dytk=%s'%(self.userid,self._signature,self.dytk)

url_list=self.handle_url()

download_url,title_list=self.get_download_url(url_list)

foriinrange(len(download_url)):

url=download_url[i]

title=title_list[i]

self.videodownloader(url,title)

if__name__=='__main__':

#创建对象

#传入三个参数,user_id,_signature,dytk

douyin_spider=douyin_spider('95870186531','RFE1JhAbHxD7J8TA9HCumURRNT','539f2c59bb57577983b3818b7a7f32ef')

douyin_spider.run()

print'******DouYin_spider@Awesome_Tang、******'

问题

开始说了,目前还存在一个问题,我们看接口地址可以发现,目前需要5个参数分别是:

user_id, max_cursor,count,_signature, dytk

前面三个都没问题,而且我看有的博主5/6月份都文章都还只需要前三个参数,_signature, dytk是两个加密之后的参数,不知道咋加密的,而且selenium似乎也没有获取后台请求地址的方法,返回的视频地址也没有在页面进行渲染,所以现在还需要点击分享链接之后手动填入_signature, dytk两个值,有点冒傻气...

版权申明:本站文章均来自网络,如有侵权,请联系01056159998 邮箱:itboby@foxmail.com

特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值