抖音没有电脑版,刚学完scrapy,又懂一点django,哈!刚好可以搭建个简陋网页版抖音。
教程分为2部分,一部分是爬虫部分,另一部分是django网站部分。2部分都是些简单的基础知识,没啥高深的东西,适合初学者看看,下面是效果图。
题主的运行环境:
Windows10
python3.6
scrapy1.4
django2.1
一、scrapy爬虫部分
1.先用fiddler对抖音app抓包,关于fiddler怎么抓包内容较多,大家自己百度下。不想自己抓包的直接使用我下面那个接口吧。
这个category接口是爬取热门音乐和热门挑战的。题主使用的是下面这个
这个接口每次请求随机返回20条左右视频信息,下面是评论信息接口
2.创建scrapy工程
(1)打开cmd进入你想创建工程的目录输入(“douyin”就是工程的目录名,随意起名):scrapy startproject douyin
(2)进入spider目录下创建爬虫,输入命令:scrapy genspider douyinSpider "a" ,这表示创建一个名为douyinSpider的爬虫,名字随意但不要个工程名相同。“a”是爬虫域名的限制范围,这里不使用就随便写了个。
(3)整个工程目录结构如下
(4)编写douyinSpider爬虫文件,代码中都有注释了
# -*- coding: utf-8 -*- import scrapy from douyin.items import DouyinItem import json import jsonpath #jsonpath是用来方便解析大点的json文件的,用法大家百度下,挺简单的 class DouyinspiderSpider(scrapy.Spider): name = 'douyinSpider' #start_urls列表实际是调用start_requests函数来处理每个url的,这里我们重写下自己的start_requests def start_requests(self): #这是抖音的一个接口,每次请求这个url将会随机返回20条左右的抖音视频信息,count控制返回信息的多少,貌似25就是最大了。我们循环访问这个接口抓取数据 url = "https://aweme.snssdk.com/aweme/v1/feed/?type=0&max_cursor=0&min_cursor=0&count=25&aid=1128" #这里循环爬取10次,dont_filter设置为True,表示不过滤重复url。因为我们每次都是请求同一个url,不设置dont_filter默认位False,只能爬取一次 for i in range(1,10): yield scrapy.Request(url,dont_filter = True) def parse(self, response): json_response = json.loads(response.body_as_unicode()) #找出返回文件中所有aweme_list下的文件,也就是抖音的视频信息列表,然后循环解析每一个视频信息,video_info就是1个抖音视频的所有信息 aweme_list = jsonpath.jsonpath(json_response,"$..aweme_list") for aweme in aweme_list: for video_info in aweme: #digg_count是点赞数,筛选出点赞数大于10w的视频进行解析 digg_count = video_info["statistics"]["digg_count"] if int(digg_count) > 10*10000: #先找出aweme_id,aweme_id好像就是每个视频的唯一标识,我们这里要把aweme_id传入下面的comment_url这个接口爬取评论信息, aweme_id = jsonpath.jsonpath(video_info,"$.statistics.aweme_id") comment_url = "https://aweme.snssdk.com/aweme/v1/comment/list/?aweme_id={}&cursor=0&count=15&aid=1128".format(aweme_id[0]) #访问comment_url这个接口爬取每个视频的评论信息,调用parse_info函数解析,meta表示将video_info中的信息传递给parse_info函数 yield scrapy.Request(comment_url,callback=self.parse_info,meta={"video_info":video_info}) else: continue def parse_info(self,response): video_info = response.meta["video_info"] #接收上面parse函数传过来的video_info信息 #这里只找出评论内容和评论点赞数,以列表形式返回 comment_json = json.loads(response.body_as_unicode()) comments = comment_json["comments"] comment_list = [] for comment in comments: text = jsonpath.jsonpath(comment,'$..text') #评论内容 digg_count = jsonpath.jsonpath(comment,'$..digg_count') #评论点赞数 comment_list.append(text+digg_count) #text+digg_count是个列表,形如["小姐姐好漂亮",1888] #将每个抖音视频所有的信息传给init_item item = self.init_item(video_info,comment_list) yield item def init_item(self, video_info,comment_list): item = DouyinItem() #作者id item["author_user_id"] = video_info["author_user_id"] #视频aweme_id item["aweme_id"] = video_info["statistics"]["aweme_id"] #视频描述 item["video_desc"] = video_info["desc"] #点赞数 item["digg_count"] = video_info["statistics"]["digg_count"] #分享数 item["share_count"] = video_info["statistics"]["share_count"] #评论数 item["comment_count"] = video_info["statistics"]["comment_count"] #评论列表 item["comment_list"] = comment_list #分享链接 item["share_url"] = video_info["share_url"] #封面图链接列表,这里只取一个 item["origin_cover"] = video_info["video"]["origin_cover"]["url_list"][0] #视频播放地址列表,这里只取一个并去掉多余参数 item["play_addr"] = video_info["video"]["play_addr"]["url_list"][0].split("&line")[0] #视频下载地址列表,这里只取一个并去掉多余参数 download_addr = video_info["video"]["download_addr"]["url_list"][0].split("&line")[0] item["download_addr"] = download_addr return item
(5)items文件
# -*- coding: utf-8 -*- import scrapy class DouyinItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() author_user_id = scrapy.Field() video_desc = scrapy.Field() aweme_id = scrapy.Field() play_addr = scrapy.Field() download_addr = scrapy.Field() origin_cover = scrapy.Field() comment_info = scrapy.Field() comment_list = scrapy.Field() digg_count = scrapy.Field() comment_count = scrapy.Field() share_count = scrapy.Field() share_url = scrapy.Field()
(6)pipelines文件,题主这里使用的是mysql数据库,需要安装pymysql库。解析json文件的jsonpath库
# -*- coding: utf-8 -*- # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html import pymysql import datetime class DouyinPipeline(object): #初始化连接MySQl数据库,这里charset一定要设置为utf8mb4,这样才可以存储表情符号,抖音中是有很多表情符号的,创建数据库时也要编码设置为utf8mb4。下面passwd输入自己的密码 def __init__(self): self.connect = pymysql.connect( host = "127.0.0.1", port = 3306, db = "douyin", user = "root", passwd = "123456", charset = 'utf8mb4', use_unicode = True ) self.cursor = self.connect.cursor() print("连接数据库成功,正在存入数据库...") def process_item(self, item, spider): #执行sql语句,判断数据库中是否有此条视频信息,没有就插入,有就跳过,这里跳过没有更新数据库,因为更新也就更新下评论内容,这里就不更新了 sql = "SELECT aweme_id FROM douyin_info WHERE aweme_id = {};".format(item['aweme_id']) status = self.cursor.execute(sql) if status == 0: self.cursor.execute( """insert into douyin_info(create_time,author_user_id, aweme_id, video_desc, digg_count ,share_count, comment_count,comment_list,share_url,origin_cover,play_addr,download_addr) value (%s,%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), str(item['author_user_id']), item['aweme_id'], item['video_desc'], item['digg_count'], item['share_count'], item['comment_count'], str(item['comment_list']), item['share_url'], str(item['origin_cover']), str(item['play_addr']), str(item['download_addr']) )) self.connect.commit() else:pass return item def close_spider(self,spider): self.connect.close()
(7)settings文件
# -*- coding: utf-8 -*- BOT_NAME = 'douyin' SPIDER_MODULES = ['douyin.spiders'] NEWSPIDER_MODULE = 'douyin.spiders' USER_AGENT = 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 MicroMessenger/6.5.18 NetType/WIFI Language/en' ITEM_PIPELINES = { 'douyin.pipelines.DouyinPipeline': 300, }
(8)打开mysql数据库创建数据库,数据库名为douyin,这里推荐使用navicat,字符集一定要设置为utf8mb4才可以存储表情符号
(9)创建表,表名为douyin_info
CREATE TABLE douyin_info ( auto_id INT NOT NULL primary key AUTO_INCREMENT, create_time DateTime NOT NULL, author_user_id VARCHAR(50), aweme_id VARCHAR(100), digg_count INT, video_desc VARCHAR(150), share_count INT, comment_count INT, comment_list TEXT, share_url VARCHAR(100), origin_cover VARCHAR(100), play_addr VARCHAR(100), download_addr VARCHAR(100));
(10)一切大功告成,打开cmd进入项目目录输入:scrapy crawl douyinSpider 就开始爬取数据了