python scrapy爬取抖音視頻,並用django做個簡單版網頁刷抖音視頻


抖音沒有電腦版,剛學完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 就開始爬取數據了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM