抖音带货的兴起,让抖音电商一跃成为与淘宝电商、京东电商等电商平台共同争夺电商市场的存在,与淘宝电商、京东电商等电商平台相比,抖音电商拥有独特的优势,抖音以短视频的形式能够带来巨大的流量和热度,抖音以此为基础带来全新的带货方式——短视频带货,除此之外,抖音因其高流量高热度的基础,使得开展直播带货的途径顺其自然了许多。在此背景之下,抖音电商的商品销售数据的获取和总结分析归纳对于抖音电商调整当前销售结构和形式以及对未来的规划有着重大意义。
除此之外,也给一些想要简单爬取一些抖音商品销售数据的同学们一个便捷易懂的方法。
由于通过抖音页面对商品销售数据进行爬取过于繁琐,工作量大,因此决定通过对蝉妈妈数据平台(拥有抖音商品销售数据的各大榜单)进行抖音商品销售数据的获取,又因想要通过蝉妈妈数据平台直接进行数据的获取所需要的成本和花销太大,因此决定通过以爬虫的形式对蝉妈妈数据平台的各大抖音商品销售数据榜单进行数据爬取,由新人注册蝉妈妈数据平台都会获得免费的会员时间,但免费的会员只能够查看数据,并不能对数据的直接导出,因此可以通过免费的会员使用爬虫对各大榜单数据进行爬取。
打开蝉妈妈数据平台以后,选择一个销售榜单,本文以直播带货的榜单为例,后续的网页下载、数据解析、数据存储和数据预处理都以直播带货榜单开展,其他榜单的相关处理与直播带货榜单相差不大,所以就以直播带货榜单为例,爬取方法以selenium自动化库为主。
查看网页源代码以后,简单知道每一条直播带货的数据都存储在
上图可知一条直播销售具体数据存储在
因此只要获取每个
由于为了应对反爬机制,本爬虫主要使用了selenium自动化模块,因此网页下载部分没有一个单独的模块用来进行网页下载,因此也就没有ip代理池、headers、cookies的设置,所有就只有一行代码进行网页的下载(selenium.webdriver中自带的网页下载方法)
html = driver.page_source
根据上述的网页源代码分析,对每一个
数据解析单独建立一个模块。解析过程中使用bs解析器。
from bs4 import BeautifulSoup from selenium import webdriver class WatchingParser: def __init__(self): self.base_url = "https://www.chanmama.com/" self.driver = webdriver.Chrome() def get_data(self,html_content): print("开始解析数据") if html_content is None: return None # 汇总当前页所有数据 result_data = [] soup = BeautifulSoup(html_content,'lxml') # 获取所有tr标签 all_data = soup.find_all('tr') all_data = all_data[2:] i = 1 # 分析每一个tr标签的数据 try: while i < 51: data = all_data[i] # 获取直播名称 name = data.find_all('a',class_='text-decoration-none c333 link-hover cursor-pointer') watch_name = name[0].text watch_name = watch_name.replace("\n", "") watch_name = watch_name.replace(" ", "") # print(watch_name) # 获取达人名称 people_name = name[1].text people_name = people_name.replace("\n", "") people_name = people_name.replace(" ", "") # print(people_name) # 获取达人粉丝数 fans_quantity = data.find('span',class_='c999').text fans_quantity = fans_quantity.replace("\n", "") fans_quantity = fans_quantity.replace(" ", "") # print(fans_quantity) # 获取开播时间 watch_start = data.find('td',class_='fs14').text watch_start = watch_start.replace("\n", "") watch_start = watch_start.replace(" ", "") # print(watch_start) # 获取直播时长 watch_all = data.find_all('div',class_='text-align-left pl15') watch_longth = watch_all[1].text watch_longth = watch_longth.replace("\n", "") watch_longth = watch_longth.replace(" ", "") # print(watch_longth) # 获取人气峰值 peak = data.find('td',class_='text-align-right').text peak = peak.replace("\n", "") peak = peak.replace(" ", "") # print(peak) # 获取观看人次 watching_people = data.find('td',class_='divider text-align-right').text watching_people = watching_people.replace("\n", "") watching_people = watching_people.replace(" ", "") # print(watching_people) commodity = data.find_all('div',class_='text-align-right pr20') # 获取商品数 commodity_quantity = commodity[0].text commodity_quantity = commodity_quantity.replace("\n", "") commodity_quantity = commodity_quantity.replace(" ", "") # print(commodity_quantity) # 获取销售额 sale_money = commodity[1].text sale_money = sale_money.replace("\n", "") sale_money = sale_money.replace(" ", "") # print(sale_money) # 获取销售量 sale_quantity = commodity[2].text sale_quantity = sale_quantity.replace("\n", "") sale_quantity = sale_quantity.replace(" ", "") # print(sale_quantity) item = { 'wacth_name' : watch_name, 'people_name' : people_name, 'fans_quantity' : fans_quantity, 'watch_start' : watch_start, 'watch_longth' : watch_longth, 'peak' : peak, 'wacthing_people' : watching_people, 'commodity_quantity' : commodity_quantity, 'sale_money' : sale_money, 'sale_quantity' : sale_quantity } # print(item) result_data.append(item) i = i + 1 # print(i) except Exception as e: print(e) return result_data
数据存储部分也单独建立一个模块。
import csv import pymongo class DataStorage: def __init__(self): self.alldata=[] def store_data(self, data): if data is None: return self.alldata.append(data) def watching_output_file(self,filename): print("开始将数据写入文件") file = open(filename, 'w', newline='', encoding='utf-8-sig') csv_writer = csv.writer(file, dialect='excel') #由于数据存储的是二维数组([{,},{},{},{}] 形式的,因此需要先读取一个{},再对里面的信息进行键值对分离 for data in self.alldata: print(data) for note in data: print(note) cols = note.items() row = [] for key, value in cols: row.append(value) csv_writer.writerow(row) file.close()
主程序运行,将数据解析和数据存储模块导入。
import time from WatchingParser import * from DataStorage import * from selenium import webdriver # 达人直播带货榜单数据获取 class WacthingMain: def __init__(self): self.parser = WatchingParser() self.datastorage = DataStorage() def set_limit(self, limit): self.urlmanager.set_limit(limit) def crawl(self, root_url, filename): driver = webdriver.Chrome(executable_path="D:\Spider\tiktok\chromedriver\chromedriver.exe") # 模拟登录,访问直播带货页面 driver.get(root_url) time.sleep(7) # 进行账号的模拟登录 driver.find_element_by_id('e2e-login-btn').click() time.sleep(3) driver.find_element_by_id('e2e-login-username').send_keys('17858855600') driver.find_element_by_id('e2e-login-password').send_keys('123456') driver.find_element_by_id('e2e-login-submit').click() time.sleep(5) # 进行30页的数据爬取 i = 1 while i < 21: print("进行第" + str(i) + "页数据抓取") try: time.sleep(7) html = driver.page_source # 对当前网页的html进行解析,获取当前商品信息,存入data data = self.parser.get_data(html) print(data) # 将data存入到datastorage的all_data属性中 if data: self.datastorage.store_data(data) print("成功抓取到第" + str(i) + "页数据") except Exception as e: print(e) print("第" + str(i) + "页抓取失败") #下一页点击 driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div/div/div/div/div[2]/div[4]/div/button[2]/i").click() i = i + 1 driver.quit() self.datastorage.watching_output_file(filename) if __name__ == '__main__': root_url="https://www.chanmama.com/liveSearch?keyword=&search_type=0&follower_count=&gift_count=&volume=&is_take_product=0" spider_main = WacthingMain() spider_main.crawl(root_url,'D:\Spider\tiktok\wacthing_data.csv')
对爬取到的数据进行一些简单的数据预处理,以下为爬取到的数据。
使用excel中的分列功能,对其进行以,为分隔符进行分割,并且使用删除重复值,得到以下的数据表。
由于粉丝数等具有w字单位的,会对后续的分析有影响,所有统一将w替换成000,将其变成数值类型,方便后续的分析。
由于销售量和销售额是一个区间,再根据其是一个固定的划分区间,具有一个递增的规律,因此对每个区间进行等级赋值,得到销售量等级数据列,方便后续的分析。得到以下的数据表。
总体代码运用了selenium自动化模块,能够有效地应对平台的反爬机制,从而有效地获取到网页的数据,但又由于使用的是selenium自动化模块,所以总体的代码运行效率不是很高,耗时长。
整个数据预处理总体上使用了excel的功能,虽有效地解决了要解决的问题,但有些处理过程并不简单有效率,预处理只做了剔除重复值,删除空白字段,和对销售区间进行等级映射赋值,还有其他的预处理过程并未进行,使得数据格式或有效程度未达到最大。