exec.py 4.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. # -*- encoding: utf-8 -*-
  2. '''
  3. @File : exec.py
  4. @Time : 2023年06月19日 20:29:33 星期一
  5. @Author : erma0
  6. @Version : 1.0
  7. @Link : https://erma0.cn
  8. @Desc : 抖音爬虫命令行
  9. '''
  10. import os
  11. import click
  12. from loguru import logger
  13. from browser import Browser
  14. from spider import Douyin
  15. @click.command()
  16. @click.option('-u', '--urls', type=click.STRING, multiple=True, help='账号/话题/音乐等URL或文件路径(文件内一行一个URL),可多次输入。采集本账号喜欢/收藏/关注/粉丝时可空')
  17. @click.option('-n', '--num', default=-1, help='选填。最大采集数量,默认不限制')
  18. @click.option('-g', '--grab', is_flag=True, help='选填。只采集信息,不下载作品')
  19. @click.option('-d', '--download', is_flag=True, help='选填。不采集,直接下载之前采集过的配置文件,用于下载失败时重试')
  20. @click.option('-l', '--login', default=True, is_flag=True, help='选填。指定是否登录,默认要登录,可避免一些风控,采集关注粉丝等信息时必须登录')
  21. @click.option('-m', '--mstoken', default=False, is_flag=True, help='选填。指定是否在下载配置文件中设置UA及mstoken,默认不需要,出现下载0kb时尝试使用此参数')
  22. @click.option('-h', '--headless', default=True, is_flag=True, help='选填。指定是否使用headless模式(不显示浏览器界面),默认为True,出现问题时使用此参数以便观察')
  23. @click.option('-t',
  24. '--type',
  25. type=click.Choice(['post', 'like', 'music', 'search', 'follow', 'fans', 'collection', 'video', 'favorite', 'id'],
  26. case_sensitive=False),
  27. default='post',
  28. help='选填。采集类型,支持[主页作品/喜欢/音乐/搜索/关注/粉丝/合集/单作品/收藏/抖音号查信息],默认采集post作品,能够自动识别搜索/音乐/合集/单作品以及本账号的喜欢/收藏。')
  29. @click.option('-b',
  30. '--browser',
  31. type=click.Choice(["chrome", "msedge", "chrome-beta", "msedge-beta", "msedge-dev"], case_sensitive=False),
  32. default='msedge',
  33. help='选填。浏览器类型,默认使用稳定版EDGE,可选[chrome/msedge]以及beta或dev版本,如需使用Firefox或WebKit请自行修改browser文件')
  34. @click.option('-p', '--path', type=click.STRING, default='下载', help='选填。下载文件夹,默认为[下载]')
  35. @click.option('-pt',
  36. '--pathtype',
  37. type=click.Choice(["id", "title"], case_sensitive=False),
  38. default='id',
  39. help='选填。文件夹命名格式,默认为[type]_[id],可选[title](不需要主页作品增量采集时建议填title,即使用[标题/昵称/关键词]来命名)')
  40. def main(urls, num, grab, download, login, mstoken, headless, type, browser, path, pathtype):
  41. """
  42. 命令行
  43. """
  44. if not urls: # 未输入目标地址
  45. if type in ['like', 'favorite', 'follow', 'fans']: # 采集本账号
  46. edge = Browser(channel=browser, headless=headless)
  47. start(edge.context, urls, num, grab, download, type, path, pathtype, mstoken)
  48. edge.stop()
  49. return
  50. elif type in ['post', 'music', 'search', 'collection', 'video']: # 自动识别类型
  51. urls = (input('目标URL或文件路径:'), )
  52. else:
  53. print('请输入目标URL或文件路径')
  54. return
  55. edge = Browser(channel=browser, need_login=login, headless=headless)
  56. for url in urls:
  57. if os.path.exists(url): # 文件路径
  58. with open(url, 'r', encoding='utf-8') as f:
  59. lines = f.readlines()
  60. if lines:
  61. for line in lines:
  62. start(edge.context, line, num, grab, download, type, path, pathtype, mstoken)
  63. else:
  64. logger.error(f'[{url}]中没有发现目标URL')
  65. else:
  66. start(edge.context, url, num, grab, download, type, path, pathtype, mstoken)
  67. edge.stop()
  68. def start(context, url, num, grab, download, type, path, pathtype, mstoken):
  69. a = Douyin(context, url, num, type, path, pathtype, mstoken)
  70. if download: # 不需要新采集
  71. a.has_more = False
  72. a.run()
  73. if grab or type in ['follow', 'fans', 'id']: # 不需要下载
  74. return
  75. a.download()
  76. if __name__ == "__main__":
  77. main()