抖音没有电脑版,刚学完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 就开始爬取数据了