吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5598|回复: 11
收起左侧

[Python 转载] 快速爬取抖音作者主页视频的异步爬虫

  [复制链接]
yinghihi 发表于 2022-9-21 19:51
此爬虫只是对站内另一爬虫的异步改写,原帖在这里:https://www.52pojie.cn/thread-1685010-1-1.html经测试,在爬取时有时会有卡顿情况,但爬虫本身并未报错,所以这个应该是api接口不能及时传回数据导致的,耐心等待下即可。

演示:
Peek-2022-09-21-19-39.gif


爬虫代码:
[Python] 纯文本查看 复制代码
import re
import os
import requests
import aiohttp
import aiofiles
import asyncio # win下注释掉此行
import uvloop

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())    # win下注释掉此行
headers = {
    'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'
}
 
quantity = 0  # 初始视频数量
indexNum = 1 
async def start(session,sec_uid,max_cursor='0'):
    global quantity
    apiUrl = f'https://m.douyin.com/web/api/v2/aweme/post/?reflow_source=reflow_page&sec_uid={sec_uid}&count=21&max_cursor={max_cursor}'
    data = await getData(session,apiUrl)  # 请求数据
    # print(data)
    max_cursor = data['max_cursor']  # 获取max_cursor
    aweme_list = data['aweme_list']  # 获取视频列表
    tasks = []
    for aweme in aweme_list:  # 遍历视频列表
        quantity += 1  # 视频数量+1
        video_name = aweme['desc']  # 获取视频名称
        video_url = aweme['video']['play_addr']['url_list'][0]  # 获取视频地址
        nickname = aweme['author']['nickname']  # 获取作者昵称
        video_name = video_name.replace('\n', ' ')  # 吧\n替换成空格
        video_name = re.sub(r'[\/:*?"<>|]', '-', video_name)  # 替换文件名中的特殊字符
        # print(f'正在下载第{quantity}个视频:{video_name}')  # 打印视频名称
        if video_name == '':
            video_name = str(quantity) + nickname  # 如果视频名称为空,就用视频数量+作者昵称作为视频名称
        task = asyncio.create_task(downVideo(session,video_url,video_name,nickname))
        tasks.append(task)

    await asyncio.wait(tasks)    
    has_more = data['has_more']
    if not has_more:  # 如果has_more为False 说明没有更多视频了
        print(f'视频下载结束!共下载{quantity}个视频')
        return  # 退出循环
    else:
        await start(session,sec_uid,max_cursor)

async def downVideo(session,url,videoname,nickname):
    global indexNum
    async with session.get(url,headers=headers) as resp:
        if resp.status == 200:
            videoContent = await resp.read()
            downloadPath = "/home/yin/download"
            if not os.path.exists(f'{downloadPath}/{nickname}'):  # 如果作者文件夹不存在,就创建
                os.mkdir(f'{downloadPath}/{nickname}')  # 如果作者文件夹不存在,就创建一个
            async with aiofiles.open(f'{downloadPath}/{nickname}/{videoname}.mp4', 'wb') as f:
                print(f'正在下载第{indexNum}个视频:{videoname}')  # 打印视频名称
                await f.write(videoContent)
                indexNum +=1

async def getData(session,url):
    async with session.get(url,headers=headers) as resp:
        if resp.status == 200 or resp.status ==302:
            apiJson = await resp.json()
            return apiJson

async def indexInfo(url):
    try:
        sec_uid = re.findall('user/(.*)\?', url)[0]  # 从url中提取sec_uid
    except:
        sec_uid = re.findall('user/(.*)', url)[0]
    return sec_uid

async def main(offset):
    secUid = await indexInfo(offset)
    async with aiohttp.ClientSession() as session:
        await start(session,secUid)
 
if __name__ == '__main__':
    url = input('请输入作者主页链接:')  # 输入作者主页链接 例:https://www.douyin.com/user/MS4wLjABAAAAm-YgirNQo_9nm1B8TNynOD5ZrYBtesVrgBuaZaS2dzQ?vid=6907843457583205646
    url = requests.get(url, headers=headers).url  # 获取重定向后的url
    asyncio.run(main(url))

免费评分

参与人数 5吾爱币 +5 热心值 +5 收起 理由
haiyangnanzi + 1 + 1 小白支持
Quincy379 + 1 + 1 学习下
lgc81034 + 1 谢谢@Thanks!
theStyx + 2 + 1 热心回复!
smartfind + 1 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

lanlinux 发表于 2022-9-22 08:52
厉害 我也试试 楼主牛皮
xiaohanGG 发表于 2022-12-7 23:39
import re
import os
import requests
import aiohttp
import aiofiles



headers = {
    'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'
}
  
quantity = 0  # 初始视频数量
indexNum = 1
async def start(session,sec_uid,max_cursor='0'):
    global quantity
    apiUrl = f'https://m.douyin.com/web/api/v2/aweme/post/?reflow_source=reflow_page&sec_uid={sec_uid}&count=21&max_cursor={max_cursor}'
    data = await getData(session,apiUrl)  # 请求数据
    # print(data)
    max_cursor = data['max_cursor']  # 获取max_cursor
    aweme_list = data['aweme_list']  # 获取视频列表
    tasks = []
    for aweme in aweme_list:  # 遍历视频列表
        quantity += 1  # 视频数量+1
        video_name = aweme['desc']  # 获取视频名称
        video_url = aweme['video']['play_addr']['url_list'][0]  # 获取视频地址
        nickname = aweme['author']['nickname']  # 获取作者昵称
        video_name = video_name.replace('\n', ' ')  # 吧\n替换成空格
        video_name = re.sub(r'[\/:*?"<>|]', '-', video_name)  # 替换文件名中的特殊字符
        # print(f'正在下载第{quantity}个视频:{video_name}')  # 打印视频名称
        if video_name == '':
            video_name = str(quantity) + nickname  # 如果视频名称为空,就用视频数量+作者昵称作为视频名称
        task = asyncio.create_task(downVideo(session,video_url,video_name,nickname))
        tasks.append(task)

    await asyncio.wait(tasks)   
    has_more = data['has_more']
    if not has_more:  # 如果has_more为False 说明没有更多视频了
        print(f'视频下载结束!共下载{quantity}个视频')
        return  # 退出循环
    else:
        await start(session,sec_uid,max_cursor)

async def downVideo(session,url,videoname,nickname):
    global indexNum
    async with session.get(url,headers=headers) as resp:
        if resp.status == 200:
            videoContent = await resp.read()
            downloadPath = "/home/yin/download"
            if not os.path.exists(f'{downloadPath}/{nickname}'):  # 如果作者文件夹不存在,就创建
                os.mkdir(f'{downloadPath}/{nickname}')  # 如果作者文件夹不存在,就创建一个
            async with aiofiles.open(f'{downloadPath}/{nickname}/{videoname}.mp4', 'wb') as f:
                print(f'正在下载第{indexNum}个视频:{videoname}')  # 打印视频名称
                await f.write(videoContent)
                indexNum +=1

async def getData(session,url):
    async with session.get(url,headers=headers) as resp:
        if resp.status == 200 or resp.status ==302:
            apiJson = await resp.json()
            return apiJson

async def indexInfo(url):
    try:
        sec_uid = re.findall('user/(.*)\?', url)[0]  # 从url中提取sec_uid
    except:
        sec_uid = re.findall('user/(.*)', url)[0]
    return sec_uid

async def main(offset):
    secUid = await indexInfo(offset)
    async with aiohttp.ClientSession() as session:
        await start(session,secUid)

async def do_not_raise(user_defined_coroutine):
    try:
        await user_defined_coroutine
    except CancelledError:
        raise
    except Exception:
        logger.warning("User defined logic raises an exception", exc_info=True)
        # ignore
        


if __name__ == '__main__':
    url = input('请输入作者主页链接:')  # 输入作者主页链接 例:https://www.douyin.com/user/MS4wLjABAAAAm-YgirNQo_9nm1B8TNynOD5ZrYBtesVrgBuaZaS2dzQ?vid=6907843457583205646
    url = requests.get(url, headers=headers).url  # 获取重定向后的url
    asyncio.run(main(url))


报错Traceback (most recent call last):
  File "C:/Program Files/Python311/dy.py", line 89, in <module>
    asyncio.run(main(url))
NameError: name 'asyncio' is not defined
刻下ing 发表于 2022-9-22 08:24
pangiggs 发表于 2022-9-22 08:49
厉害,直接在ide里面运行吗?
yuweb 发表于 2022-9-22 08:57
嘿嘿我也来试一下
teondy 发表于 2022-9-22 10:37
厉害 试试看
开创者 发表于 2022-10-1 17:35
uvloop 这个无论如何也安装不成功,知道原因吗?
py3.7 pip20.2.4
安装时报错误:
[HTML] 纯文本查看 复制代码
Collecting uvloop
  Using cached [url]https://mirrors.aliyun.com/pypi/packages/ba/86/6dda1760481abf244cbd3908b79a4520d757040ca9ec37a79fc0fd01e2a0/uvloop-0.17.0.tar.gz[/url] (2.3 MB)
    ERROR: Error [WinError 2] 系统找不到指定的文件。 while executing command python setup.py egg_info
ERROR: Could not install packages due to an EnvironmentError: [WinError 2] 系统找不到指定的文件。

 楼主| yinghihi 发表于 2022-10-1 20:20
开创者 发表于 2022-10-1 17:35
uvloop 这个无论如何也安装不成功,知道原因吗?
py3.7 pip20.2.4
安装时报错误:

uvloop不支持windows,注释掉就可以了

免费评分

参与人数 1吾爱币 +1 收起 理由
开创者 + 1 热心回复!

查看全部评分

开创者 发表于 2022-10-1 22:51
yinghihi 发表于 2022-10-1 20:20
uvloop不支持windows,注释掉就可以了

好的,两行删除就行了。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 01:39

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表