爬虫案例—京东数据爬取、数据处理及数据可视化(效果+代码)

一、数据获取

        使用PyCharm(引用requests库、lxml库、json库、time库、openpyxl库和pymysql库)爬取京东网页相关数据(品牌、标题、价格、店铺等)

数据展示(片段):

        京东网页有反爬措施,需要自己在网页登录后,获取cookie,加到请求的header中(必要时引入time库,设置爬取睡眠时间降低封号概率)

爬取代码(片段):

###获取每一页的商品数据
def getlist(url,brand):
    global count #定义一个全局变量,主要是为了确定写入第几行
    # url="https://search.jd.com/search?keyword=笔记本&wq=笔记本&ev=exbrand_联想%5E&page=9&s=241&click=1"
    res = requests.get(url,headers=headers)
    res.encoding = 'utf-8'
    # text = (res.text).replace("")
    text = res.text
    selector = etree.HTML(text)
    list = selector.xpath('//*[@id="J_goodsList"]/ul/li')#获取数据所在

    for i in list:
        title = i.xpath('.//div[@class="p-name p-name-type-2"]/a/em/text()')[0].strip()#商品名称
        price = i.xpath('.//div[@class="p-price"]/strong/i/text()')[0]#商品价格
        shop = i.xpath('.//div[@class="p-shop"]/span/a/text()')[0] #获取店铺名称
        #获取评论数的id值
        # product_id = i.xpath('.//[@class="p-commit"]/strong/a/@id')[0].replace("J_comment_","")
        # comment_count = commentcount(product_id)
        # print("目前条数="+str(count))

爬取完后直接存入数据库:

# 实现将数据写入到数据库中吗,提前将库和表创建好,创建表结构如下:
"""CREATE TABLE jd.shuju(
    id INT PRIMARY KEY AUTO_INCREMENT,
    brand VARCHAR(100) CHARACTER SET utf8,
    title VARCHAR(100) CHARACTER SET utf8,
    price VARCHAR(100) CHARACTER SET utf8,
    shop VARCHAR(100) CHARACTER SET utf8,
    comment_count VARCHAR(100) CHARACTER SET utf8);
"""

conn = pymysql.connect(
    host='127.0.0.1',
    user='root',
    passwd='',
    port=3306,
    db='jd',
    charset='utf8',
    use_unicode=True
)
# print("连接成功")
cursor = conn.cursor()  # 执行完毕返回的结果集默认以元组显示
# 向sql中插入数据
try:
    sql = f"insert ignore into shuju111(brand,title,price,shop) values('{brand}','{title}','{price}','{shop}')"
    cursor.execute(sql)  # 执行SQL语句
    # print("插入完一条语句")
    cursor.close()  # 关闭光标对象
    conn.commit()  # 提交
    conn.close()  # 关闭数据库
except:
    print("跳过1次插入")
    continue
#向表中插入数据
outws.cell(row=count, column=1, value=str(count - 1))  # 从第一行开始
outws.cell(row=count, column=2, value=str(brand))
outws.cell(row=count, column=3, value=str(title))
outws.cell(row=count, column=4, value=str(price))
outws.cell(row=count, column=5, value=str(shop))
# outws.cell(row=count, column=6, value=str(CommentCount))
count = count + 1  # 自动跳入下一行

二、数据处理

        对所爬取数据中无关数据进行清洗(符号的替换)

代码部分:

# 调用函数模拟请求获取评论数
def commentcount(product_id):
    url = "https://club.jd.com/comment/productCommentSummaries.action?referenceIds="+str(product_id)+"&callback=jQuery8827474&_=1615298058081"
    res = requests.get(url, headers=headers)
    res.encoding = 'utf-8'   #字符转换
    text = (res.text).replace("jQuery8827474(","").replace(");","")  #替换掉前面出现的jQuery5597865
    text = json.loads(text)   #将字符串转换为json格式
    comment_count = text['CommentsCount'][0]['CommentCountStr']

    comment_count = comment_count.replace("+", "")
    #对万进行操作,数据清洗
    if "万" in comment_count:
        comment_count = comment_count.replace("万","")
        comment_count = str(int(comment_count)*10000)
    return comment_count

三、数据可视化

        调用数据库数据利用matplotlib.pyplot进行图像绘制(主要根据品牌、店铺、平均价格进行相关数据可视化)

品牌—数量可视化效果:

代码部分:

#画品牌和数量的图表
plt.title('品牌-数量')
plt.xlabel('品牌')
plt.ylabel('品牌数量')
x = ['联想(lenovo)', 'Apple', '宏碁(acer)', '华为(HUAWEI)', 'ThinkPad', '戴尔(DELL)', '小米(MI)']
y = [count_pp[item] for item in x]
plt.bar(x, y)
plt.show()

 店铺—数量可视化效果:

 

代码部分:

#店铺及数量表
count_dp = {'联想京东自营旗舰店':0,'联想京东自营官方旗舰店':0,'联想商用丽邦专卖店':0,
            '联想商用融合汇通专卖店':0,'联想扬天京东自营授权旗舰店':0}
sql1 = "select * from shuju where brand = '联想(lenovo)' and id<24"#分析前二十个店铺
cursor.execute(sql1)
results1 = cursor.fetchall()  # 以元组的形式返回
for row in results1:
    count_dp[row['shop']] += 1
plt.title('店铺-数量')
plt.xlabel('店铺')#横坐标代表含义
plt.ylabel('店铺数量')
x = ['联想京东自营旗舰店','联想京东自营官方旗舰店','联想商用丽邦专卖店',
     '联想商用融合汇通专卖店','联想扬天京东自营授权旗舰店']
y = [count_dp[item] for item in x]
plt.bar(x, y)
plt.show()

 品牌—价格可视化效果:

 代码部分:

#根据平均价格分析
plt.title('品牌-价格')
plt.xlabel('品牌')
plt.ylabel('品牌价格')
x = ['联想(lenovo)', 'Apple', '宏碁(acer)', '华为(HUAWEI)',
     'ThinkPad', '戴尔(DELL)', '小米(MI)']
y = [price_total[item]/count_pp[item] for item in x]
plt.bar(x, y)
plt.show()

 品牌占比例可视化效果:

 代码部分:

#饼图分析品牌占比
explode = (0,0,0,0.1,0,0,0,0)
candidate = [key for key in count_pp]   #拿取品牌的键名
votes = [value for value in count_pp.values()]   #拿取品牌的键值
plt.figure(figsize=(10, 10), dpi=100)
plt.pie(votes, labels=candidate, explode=explode, autopct="%1.2f%%", shadow=False, startangle=90,
        textprops={'fontsize':15},labeldistance=1.05)
#labels饼图外侧显示的说明文字,explode为突出某个值,autopct设置百分比小数位,shadow表示阴影,
# startangle起始绘制角度,默认图是从x轴正方向逆时针画起,设定=90则从y轴正方向画起;
# labeldistance:label标记的绘制位置,相对于半径的比例,默认值为1.1, 如<1则绘制在饼图内侧;
plt.legend(loc='upper right',fontsize=6)   #设置图例位置和大小
plt.title("各品牌占比")
plt.axis('equal')
plt.show()

 店铺占比例可视化效果:

 代码部分:

#画环形饼图
candidate1 = [key for key in count_dp]   #拿取品牌的键名
votes1 = [value for value in count_dp.values()]   #拿取品牌的键值
plt.figure(figsize=(10, 10), dpi=100)
explode1=[0,0,0,0,0]
plt.pie(votes1, labels=candidate1, explode=explode1, autopct="%1.2f%%", shadow=False, startangle=90,
        textprops={'fontsize':15},pctdistance=0.85,labeldistance=1.05)
plt.pie([1],radius=0.7,colors='w')  #在内部画一个白色的圆
plt.legend(loc='upper left',fontsize=6)
plt.title("各店铺占比")
plt.axis('equal')
plt.show()

四、说明

        代码仅提供主要部分,许多功能都可以优化改进,个人水平有限,仅供参考,勿喷谢谢

        遇到问题可以多百度!

物联沃分享整理
物联沃-IOTWORD物联网 » 爬虫案例—京东数据爬取、数据处理及数据可视化(效果+代码)

发表评论