爬取网址:
http://search.dangdang.com/?key=%CE%C0%D2%C2&category_id=10010336&page_index=1
前言
利用python实现某网站男士卫衣数据爬取及可视化分析(对任课老师下发任务的一个小总结),实战次数少,代码过程中若有不当之处,还望各位大佬们私信留言哦~
开发工具
python3.8
相关模块:pandas,pyecharts、以及python自带的一些模块
一、数据采集(Requests、BeautifulSoup)
1、基本准备
- 导入需要的库
import requests
from bs4 import BeautifulSoup
- 在headers中指定user-agent的值,实现用户代理
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/98.0.4758.102 Safari/537.36 Edg/98.0.1108.56 "
}
2、主要代码实现
- 通过一级页面获取商品页数跳转规律,同时将页数作为返回值传递给原始url进行拼接(这样做是为了实现页面自动翻页)
def pageSize():
url = "http://search.dangdang.com/?key=%CE%C0%D2%C2&category_id=10010336&page_index=1"
r = requests.get(url, headers=headers)
bs = BeautifulSoup(r.text, "html.parser")
ulTag = bs.find("ul", attrs={"name": "Fy"})
liTag = int(ulTag.find_all("li")[-3].string)
return liTag
if __name__ == "__main__":
pageNum = pageSize()
for i in range(1, pageNum + 1):
url = "http://search.dangdang.com/?key=%CE%C0%D2%C2&category_id=10010336&page_index=" + str(i)
getWebContent(url)
- 将拼接后的url作为参数传递到函数getWebContent,以此获取所有网页内容
def getWebContent(url):
r = requests.get(url, headers=headers)
parseContent(r.text)
- 对获取到的网页内容进行解析同时写入txt文件
此处的代码看起来有些繁杂,但因笔者习惯于将这种解析网页内容和存储数据等相关代码写在一起,希望大家能够理解一下啦
def parseContent(content):
bs = BeautifulSoup(content, "html.parser")
f = open("dangDang.txt", mode="a+", encoding="utf-8")
ulTag = bs.find("ul", class_="bigimg cloth_shoplist") # 一整个页面的商品信息
liTags = ulTag.find_all("li", {
"ddt-pit": True}) # 传递{"ddt-pit":True}的第二个参数会将结果限制为li具有ddt-pit属性的标签
for liTag in liTags:
price = liTag.find("p", class_="price").span.getText() # 商品价格
goodsName = liTag.find("p", class_="name").a.getText() # 商品评论人数
advertisement = liTag.find("p", class_="search_hot_word").getText() # 广告语
shopName = liTag.find("p", class_="link").a.getText() # 所属店铺名字
global reviewNum, stars # 需要对没有星级的商品做筛选,或者是review=None
try:
stars = liTag.find("p", class_="star").span.span['style'] # 星级评价
reviewNum = liTag.find("p", class_="star").a.getText() # 商品评论人数
except:
pass
allInformation = price + ";" + goodsName + ";" + advertisement + ";" + stars + reviewNum + ";" + shopName
f.write(allInformation + "\n")
f.close()
3、结果展示
以上就是数据采集的全部内容啦,代码的实现都非常简单,理解起来也是十分容易的,但是有的地方做的处理简单粗暴些(就比如try…except…那里),但是总体来讲还是很不错的,
二、数据处理
这个模块主要是在jupyter里面运行!!!
1、加载数据
- 导入采集到的数据,同时添加列名(注意源数据分隔符)
import pandas as pd
import numpy as np
data = pd.read_table("dangDang.txt", sep=";",encoding = 'utf-8',names = ['单价','商品名称','广告语','评论星级','评论条数','店铺名称']) # 导入原始数据
data.head(5)
结果展示
2、查看数据
- 通过info函数查看
data.info()
结果展示
3、处理数据
- 对单价这列数据进行符号的替换以及数据类型的转换,以便后面进行可视化分析
data['单价'] = data['单价'].str.replace("¥","").astype('float')
data['单价']
结果展示
- 用replace将【】及其中间的内容去除
data['商品名称']=data['商品名称'].str.replace('【.*】','')
data['商品名称']
结果展示
- 处理星级相关数据内容
dataStar =data.评论星级.str.slice(6,10)#使用slice函数实现分片
dataStar = dataStar.str.replace("%"," ")#去除%
dataStars = dataStar.fillna(value=0).astype(float)#空值填充及数据类型转换
data['评论星级'] = dataStars/20
data['评论星级']
结果展示
- 对广告语中的空值进行填充
data['广告语']=data['广告语'].fillna('没有相关广告语宣传')#将空值部分替换
data['广告语']
结果展示
- 处理评论条数
data['评论条数'] = data['评论条数'].str.strip("条评论") #用strip函数将评论条数进行优化
data['评论条数']
结果展示
4、存储处理后数据
- 将处理好的数据存储为csv文件
data.to_csv('dangDang.csv')
数据处理到此就结束啦,笔者认为这个模块最重要就是要学会根据自己的需求去处理数据,拒绝做无用功!!!
三、数据存储(Mysql)
这个模块的主要作用是将csv文件的中的数据通过编写python代码上传到mysql,提高数据检索效率。废话不多说,直接上代码吧!
记得要在数据库里面提前建好相对应的数据库和表,除此之外可以将csv文件中的表头删除哦~
import pymysql
import sys
def getDB():
return pymysql.connect(host='mysql服务器地址',
user='用户名',
password='密码',
database='数据库名称',
autocommit=True) # 加上参数 autocommit 并且给它赋值 True 这样就能自动检查是否真的入库
def addRecord(listContent): # listContent 数据对象的列表
db = getDB()
cursor = db.cursor()
try:
f = open("dangDang.csv", mode="r", encoding="utf-8")
while (True):
line = f.readline()
linearrays = line.split(",")
try:
sql = "INSERT INTO dangDang(number,price,goodsName, advertisement, reviewStar, reviewNum, shopName) \
VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s')" % \
(linearrays[0], linearrays[1], linearrays[2], linearrays[3], linearrays[4], linearrays[5],
linearrays[6])
cursor.execute(sql)
except Exception:
continue
db.commit()
except Exception:
# 发生错误时回滚
print("Unexpected error:", sys.exc_info()[0])
db.rollback()
db.close()
if __name__ == "__main__":
print(addRecord([]))
结果展示
模块三的实现方法有很多种,笔者只是选择其中一种实现哦~
四、数据分析及其可视化(matplotlib、pyecharts)
这个模块的相关代码也是在juyter里面运行,不是很了解matplotlib和pyecharts可以去查阅官网
- 首先最重要的当然是导入原始数据咯
import pandas as pd
import numpy as np
data = pd.read_csv("dangDang.csv",index_col=0)
data.head(5)
结果展示
1、使用matplotlib绘制价格区间分布柱状图
import matplotlib.pyplot as plt
bins=[0,100,250,400,600,800,1100,1500]
pd.cut(data.单价,bins).value_counts()
pd.cut(data.单价,bins).value_counts().plot.bar()
柱状图展示
分析结论:由图可知,在[0,100]区间内的单价最多;其次是[100,250]、[250,400],最少的是800以上,因此可以建议商家可以对价格进行稍作调整,尽量控制在400以内,促使产品价格适应供求变化,发挥最佳促销作用,提高营销效益
2、使用pyecharts绘制店铺数量最多的饼状图
from pyecharts import options as opts
from pyecharts.charts import Pie
yName=data.groupby('店铺名称').size().to_dict().keys()#取出店铺名称
shopNum = data.groupby('店铺名称').size().to_list()
yName=list(yName)
print([list(z) for z in zip(yName, shopNum)])
c=(
Pie(init_opts=opts.InitOpts(#对图表画布进行调整
width="1100px",
height="600px",
page_title="dangDang",
)
)
.add(
"",
[list(z) for z in zip(yName, shopNum)],
radius = ["40%","55%"],
label_opts=opts.LabelOpts(
position="outside",
formatter="{a|{a}}{abg|}\n{hr|}\n {b|{b}: }{c} {per|{d}%} ",
background_color="#eee",
border_color="#aaa",
border_width=2,
border_radius=4,
rich={
"a": {"color": "#999", "lineHeight": 22, "align": "center"},
"abg": {
"backgroundColor": "#e3e3e3",
"width": "100%",
"align": "right",
"height": 22,
"borderRadius": [4, 4, 0, 0],
},
"hr": {
"borderColor": "#aaa",
"width": "100%",
"borderWidth": 0.5,
"height": 0,
},
"b": {"fontSize": 14, "lineHeight": 10},#调整各个图标相关指标的图框大小
"per": {
"color": "#eee",
"backgroundColor": "#334455",
"padding": [2, 4],
"borderRadius": 2,
},
},
),
)
.set_global_opts(
title_opts=opts.TitleOpts(#添加图表标题
title="店铺数量占比统计分析图",
title_textstyle_opts=opts.TextStyleOpts(color="black",# 主标题颜色
font_weight="bold",# 字体加粗
font_size=25,
),
),
legend_opts=opts.LegendOpts(#图例调整
pos_right="right",
orient="vertical",#调整图例朝向
item_gap=5,#图例之间的间隔
item_width=10,#图例标记的图形宽度
item_height=14
),
)
.render("shopPicture.html")
)
饼图展示
分析结论:在店铺数量饼图当中我们可以得到:占比前三名的分别为UYUK男装专卖店、UYUK服装专卖店、美特斯邦威旗舰店;排名最后的为MPF男装旗舰店、花花公子旗舰店、雅鹿男装旗舰店,因此可以建议店铺数量排名靠后的商家调整自己的营业模式,生产符合大众审美的衣服,同时提高衣服品质,美化网页外观,提高店铺知名度
整个案例实践至此就结束啦,如果你浏览到这儿,从侧面能够说明你是个对自己很有要求的人呢,嘿嘿
总结
整个案例的代码实现过程都很简单,非常适合新手小白拿来练手。笔者也是接触python不久,所以对代码的规范和使用还存在很多不足的地方,还望各位大神们能在评论区留言,如果能附上源码那就更好啦!其次对可视化结果的分析和建议都是笔者的主观判断,如果有不到位的地方,可以在评论区提出来。