吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 17504|回复: 117
收起左侧

[Python] 【原创开源】快手爬虫,根据id批量爬取用户的所有图集和视频

  [复制链接]
oGsLegolas 发表于 2020-3-6 01:02
本帖最后由 oGsLegolas 于 2020-3-23 16:32 编辑

更新日志

所有版本更新日志会记录在这里

v0.4.0(2020-03-23)

  • 修复id转eid的一些bug
  • 从该版本开始,爬取视频均为无水印 感谢@tjftjftjf

v0.3.0(2020-03-10)

  • 修复一些因为用户昵称中存在windows下文件(夹)名非法字符导致os无法写入读取的bug
  • 简单看了一点python面向对象,将核心功能提取为crawler类,降低耦合
  • 基于crawler类,分出两个文件,一个用于直接在python环境下跑代码,另一个则用于打包好exe一键运行
  • 提供exe版本

v0.2.0(2020-02-26)

  • 增加对数字id自动查询转换为eid的支持

v0.1.1 (2020-02-25)

  • 修复caption项文字保存为文件名的各种问题
  • 增加对workType 'ksong'、'single'的支持
  • 增加对于爬取过程中请求失败的解决方法
  • 增加CHANGELOG.md

写在前面

  • 项目源码地址 https://github.com/oGsLP/kuaishou-crawler
  • 代码功能如题,根据快手用户的id来爬取用户所有公开作品,包括图集和视频。
  • 原理:其实就是利用基于chromium内核的浏览器自带的devtools对所有请求进行排查找出包含作品链接的请求,然后用代码模拟请求去获得数据,再根据url下载作品保存就行了,包括一些网站的自动注册登录、操作都可以模拟。这个其实应该算是写过爬虫的同学们都知道,我自己其实不怎么用过python,也没写过什么复杂的python项目,说的不对的还请多多包涵。如果有同学还是想让我讲一下怎么爬的,我考虑再做一期详细的,其实代码应该还是可以看得懂的2333

核心代码

  • 废话不多说,上核心代码

    
    def __crawl_user(self, uid):
    if uid.isdigit():
        uid = self.__switch_id(uid)
    
    payload = {"operationName": "privateFeedsQuery",
               "variables": {"principalId": uid, "pcursor": "", "count": 999},
               "query": "query privateFeedsQuery($principalId: String, $pcursor: String, $count: Int) {\n  privateFeeds(principalId: $principalId, pcursor: $pcursor, count: $count) {\n    pcursor\n    list {\n      id\n      thumbnailUrl\n      poster\n      workType\n      type\n      useVideoPlayer\n      imgUrls\n      imgSizes\n      magicFace\n      musicName\n      caption\n      location\n      liked\n      onlyFollowerCanComment\n      relativeHeight\n      timestamp\n      width\n      height\n      counts {\n        displayView\n        displayLike\n        displayComment\n        __typename\n      }\n      user {\n        id\n        eid\n        name\n        avatar\n        __typename\n      }\n      expTag\n      __typename\n    }\n    __typename\n  }\n}\n"}
    res = requests.post(self.__data_url, headers=self.__headers, json=payload)
    
    works = json.loads(res.content.decode(encoding='utf-8', errors='strict'))['data']['privateFeeds']['list']
    
    if not os.path.exists("../data"):
        os.makedirs("../data")
    
    # 这两行代码将response写入json供分析
    # with open("data/" + uid + ".json", "w") as fp:
    #     fp.write(json.dumps(works, indent=2))
    
    # 防止该用户在直播,第一个作品默认为直播,导致获取信息为NoneType
    if works[0]['id'] is None:
        works.pop(0)
    name = re.sub(r'[\\/:*?"<>|\r\n]+', "", works[0]['user']['name'])
    
    dir = "data/" + name + "(" + uid + ")/"
    # print(len(works))
    if not os.path.exists(dir):
        os.makedirs(dir)
    
    # if not os.path.exists(dir + ".list"):
    #     print("")
    
    print("开始爬取用户 " + name + ",保存在目录 " + dir)
    print(" 共有" + str(len(works)) + "个作品")
    
    for j in range(len(works)):
        self.__crawl_work(uid, dir, works[j], j + 1)
        time.sleep(1)
    
    print("用户 " + name + "爬取完成!")
    print()
    time.sleep(1)

'''
快手分为五种类型的作品,在作品里面表现为workType属性

  • 其中两种图集: verticalmultiple,意味着拼接长图和多图,所有图片的链接在imgUrls里
  • 一种单张图片: single 图片链接也在imgUrls里
  • K歌: ksong 图片链接一样,不考虑爬取音频...
  • 视频: video 需要解析html获得视频链接
    '''

    def __crawl_work(self, uid, dir, work, wdx):
    w_type = work['workType']
    w_caption = re.sub(r"\s+", " ", work['caption'])
    w_name = re.sub(r'[\/:*?"<>|\r\n]+', "", w_caption)[0:24]
    w_time = time.strftime('%Y-%m-%d', time.localtime(work['timestamp'] / 1000))

    if w_type == 'vertical' or w_type == 'multiple' or w_type == "single" or w_type == 'ksong':
        w_urls = work['imgUrls']
        l = len(w_urls)
        print("  " + str(wdx) + ")图集作品:" + w_caption + "," + "共有" + str(l) + "张图片")
        for i in range(l):
            p_name = w_time + "_" + w_name + "_" + str(i + 1) + ".jpg"
            pic = dir + p_name
            if not os.path.exists(pic):
                r = requests.get(w_urls[i])
                r.raise_for_status()
                with open(pic, "wb") as f:
                    f.write(r.content)
                print("    " + str(i + 1) + "/" + str(l) + " 图片 " + p_name + " 下载成功 √")
            else:
                print("    " + str(i + 1) + "/" + str(l) + " 图片 " + p_name + " 已存在 √")
    elif w_type == 'video':
        w_url = self.__work_url + work['id']
        res = requests.get(w_url, headers=self.__headers_mobile,
                           params={"fid": 1841409882, "cc": "share_copylink", "shareId": "143108986354"})
        html = res.text
        waitreplace = work['id'] + '".*?"srcNoMark":"(.*?)"'
    
        v_url = re.findall(waitreplace, html)
        # pattern = re.compile(r"playUrl", re.MULTILINE | re.DOTALL)
        # script = soup.find("script", text=pattern)
        # s = pattern.search(script.text).string
        # v_url = s.split('playUrl":"')[1].split('.mp4')[0].encode('utf-8').decode('unicode-escape') + '.mp4'
        try:
            print("  " + str(wdx) + ")视频作品:" + w_caption)
        except:
            print("  这里似乎有点小错误,已跳过")
        v_name = w_time + "_" + w_name + ".mp4"
        video = dir + v_name
    
        if v_url:
            if not os.path.exists(video):
                r = requests.get(v_url[0])
                r.raise_for_status()
    
                with open(video, "wb") as f:
                    f.write(r.content)
                print("    视频 " + v_name + " 下载成功 √")
            else:
                print("    视频 " + v_name + " 已存在 √")
        else:
            print("未找到视频")
    else:
        print("错误的类型")
  • payload就是post参数,这个是在devtools的request请求底下可以找到的
  • 其实就是解析json,然后里面有图片的url和视频的id,我注释掉的两行代码可以保存完整的json的,你可以去掉注释然后看分析保存的json
  • 剩下的看源码吧,不难理解的

既然是编程语言区嘛,主要还是代码,https://github.com/oGsLP/kuaishou-crawler ,链接查看源码,这是编程语言区,不是工具软件区,我只是提供代码供大家学习,不是只让你用这个爬视频图片的。既然在编程语言区,相信大家多多少少还是会一点编程的,或者说这样的代码学习成本不是很大,不希望大家是伸手党,自己折腾出来的才是经验。

(ps: 从v0.3版本开始有打包好的exe提供了 >_>)

至于什么评分热心值和毕看着给吧23333,第一次发帖希望能帮到大家就好,如果代码真的帮到你了,或者用起来很舒服,可以github上给一波star什么的 link  各位看心情看心情

具体的使用说明,直接抄我github上的readme的原文了。。


kuaishou-crawler

As you can see, a crawler for kuaishou pictures and videos

Latest

Version 0.4.0 (2020-03-23)

  • 现在已经提供exe版本一键执行 查看 | 或者查看如何运行代码 查看
  • Python 3.7.3
    • requests
    • json
    • os
    • BeautifulSoup
    • re
  • 自v0.3.0版本开始,已用面向对象重构,核心代码在lib/crawler.py中,启动文件为crawl.py / ks.py
  • 功能:根据用户ID来爬取快手用户的作品,包括视频和图片
    1. 在preset文件(使用exe版本忽略此文件)中一行行填写用户id,若缺少文件会自动创建(目前版本已提供自动根据数字id获取真实eid)
    2. 使用时请自己用账号登录快手网站,并使用自己的cookie['headers']didweb替换,不保证源代码中对应值可用
    3. 因为快手官网会根据cookie,识别你是否在线,爬取的时候要将网页登录并挂着
      • 实测快手网站的用户验证存在30-60分钟左右的有效时长,出现list index out of range时极可能是有效期已过,登录网站验证即可
      • 暂且不知道快手官方对过多请求的处理,目前碰到的有上述验证失效,也许也会有请求达到数量会中断请求,此时注释preset中已爬取的用户id,重新开始运行脚本即可
    4. 爬取的视频暂时是带水印的(以后考虑获取无水印视频) 是无水印的 感谢@tjftjftjf提供手机抓包链接和方法
  • 注意事项:
    • 不考虑提供列表可选的批量下载功能
    • 有需要的合理功能可以issue反馈,看到后会考虑是否修改
    • 如果需要自定义自己的需求,可以拿走代码自行修改,喜欢的话给个star给个follow
    • 本代码仅供学习使用,不可违反法律爬取视频,以及私自盗用搬运视频,后果自负
    • 本代码仅供学习使用,不可违反法律爬取视频,以及私自盗用搬运视频,后果自负
    • 本代码仅供学习使用,不可违反法律爬取视频,以及私自盗用搬运视频,后果自负
    • 重要的说三遍

Run

  1. python3环境与命令行工具
  2. 进入项目目录 cd kuaishou-crawler
  3. 安装依赖 pip install -r requirements.txt
  4. 运行,有两个版本,crawl.py为运行版本,ks.py是用于构建exe的版本,当然也可以运行
    • python crawl.py / python ks.py

Release

https://github.com/oGsLP/kuaishou-crawler/releases

  • 下载打包好的exe一键运行(点击download下载即可)
    • ks.exe
    • ks.7z

Future

  • 自动根据id获取eid
  • 获取无水印视频 √
  • 进一步丰富preset预设文件的可配置选项
  • 优化代码和log
  • 提供便捷的打包exe √

Again

本代码仅供学习使用,不可违反法律爬取视频,以及私自盗用搬运视频,后果自负

免费评分

参与人数 25吾爱币 +22 热心值 +22 收起 理由
yjn866y + 1 + 1 谢谢@Thanks!
Excel_w + 1 + 1 谢谢@Thanks!
wYxPanda + 1 + 1 鼓励转贴优秀软件安全工具和文档!
jiazhilin1997 + 1 谢谢@Thanks!
liwenwusw + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
lq158 + 1 我很赞同!
ricohrh + 1 + 1 貌似接口更新了 采集不了了
geniusrot + 1 虽然没看懂,但是还是想点赞
摆渡人生 + 1 + 1 谢谢@Thanks!
羊肉串 + 1 + 1 热心回复!
blackstrike + 1 + 1 谢谢@Thanks!
bbhuai + 1 谢谢@Thanks!
晓晓韩 + 1 + 1 我很赞同!
WalkerTT + 1 + 1 厉害,小白表示没看懂无水印地址是怎么获取的
vagrantear + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
xingye688 + 1 + 1 谢谢@Thanks!
智多星 + 1 下载图集 貌似下载的图片都是损坏的 无法编辑
by9858 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
chijingzi123 + 1 + 1 有个BUG啊,如果一个用户同一天上传的视频,名字还一样的话,就会提示已存.
kevinklive + 1 + 1 热心回复!
淡忘忘淡 + 1 + 1 谢谢@Thanks!
大街上要饭的 + 1 感谢您的分享
cndaofeng + 2 + 1 用心讨论,共获提升!
观棋沽酒 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
helian147 + 1 + 1 我很赞同!

查看全部评分

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

 楼主| oGsLegolas 发表于 2020-3-9 20:05
本帖最后由 oGsLegolas 于 2020-3-12 14:21 编辑
大街上要饭的 发表于 2020-3-9 16:46
感谢楼主您能理解,这个要求是有点无理,十分感激您能回我这个小白的回复

https://github.com/oGsLP/kuaishou-crawler/raw/master/dist/ks.exe

暂时先写了一个简单易用的,以后有时间会完善的,帖子持续会更新的
已经提供exe版本,见帖子中文档详情

有三个要点

  1. 关于cookie的did值,你在电脑浏览器中打开快手网站登录后随便打开一个用户的视频作品,然后再地址栏中找到这一项,咱们以giao哥的第一个视频为例
  2. 关于用户的id,手机里点开快手用户的头像,底下会告诉你快手号的
  3. 因为快手官网会根据cookie,识别你是否在线,爬取的时候要将网页登录并挂着
 楼主| oGsLegolas 发表于 2020-4-18 22:49
这段时间忙毕设,有问题反馈的我都会记录下来,有时间再更新
 楼主| oGsLegolas 发表于 2020-8-27 23:21
Excel_w 发表于 2020-8-27 22:54
好吧我刚重新下载了一下源码,重新执行了一下exe文件,遇到视频倒是没有闪退,但是全都显示未找到视频了,源 ...

* 替换crawl.py中的did_web
* `python crawl.py`
 楼主| oGsLegolas 发表于 2020-8-12 21:55
可以用了,前两天改了一下
TechPeng 发表于 2020-3-6 10:06
谢谢,分享
bazett 发表于 2020-3-6 10:35
这个Payload是怎么得到的
 楼主| oGsLegolas 发表于 2020-3-6 12:26
bazett 发表于 2020-3-6 10:35
这个Payload是怎么得到的

打开网站,打开devtools的network,寻找里面的请求数据的request请求,

这里以giao哥为例

这里以giao哥为例
花形透 发表于 2020-3-9 02:32
占楼~~~~~
头像被屏蔽
cndaofeng 发表于 2020-3-9 03:28
提示: 作者被禁止或删除 内容自动屏蔽
大街上要饭的 发表于 2020-3-9 10:17
您对编程的维护,小的十分赞成感激,表示理解您对编程过程的热爱与维护
我在此表达敬意的同时也希望您能理解我们小白的感受,的确基本的编程技术还是应该有的,但我也希望您都能理解,所以。。。。emmm感谢您的exe
 楼主| oGsLegolas 发表于 2020-3-9 14:29
大街上要饭的 发表于 2020-3-9 10:17
您对编程的维护,小的十分赞成感激,表示理解您对编程过程的热爱与维护
我在此表达敬意的同时也希望您能理 ...

2333好吧,这两天有时间弄一个出来
大街上要饭的 发表于 2020-3-9 16:46
oGsLegolas 发表于 2020-3-9 14:29
2333好吧,这两天有时间弄一个出来

感谢楼主您能理解,这个要求是有点无理,十分感激您能回我这个小白的回复
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

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

GMT+8, 2021-5-10 01:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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