IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 七夕将至,Python爬虫分析告诉你到底要送女朋友/男朋友什么礼物 -> 正文阅读

[Python知识库]七夕将至,Python爬虫分析告诉你到底要送女朋友/男朋友什么礼物

前言

“牛郎织女”的在七夕相会的美丽爱情传说,使七夕成为了象征爱情的节日,同时也被认为是中国最具浪漫色彩的传统节日,在当代更是成为了“中国情人节”的文化符号。
随着七夕的临近,很多小伙伴都开始筹备送女朋友/男朋友的礼物了,礼物作为一种传达情感的媒介,表达了对于女朋友/男朋友的祝福和心意,但同时对于要送什么礼物,对于很多小伙伴来讲倒是选择困难,本文利用 Python 爬取某宝商品页面,为小伙伴们分析销量较高的礼物清单,以供大家参考。
(本文无任何广告行为,仅作为学习分析使用,如侵删。)

程序说明

根据不同关键字,爬取“某宝”获取商品信息(以“七夕礼物”“七夕礼物送男友”“七夕礼物送女友”等为例),根据所获取数据分析得到七夕礼物清单,并通过词云可视化的方式展示不同礼物的频率比重对比。

数据爬取

🕸? 网址构成分析

爬虫少不了网址,因此首先观察网址的构成,在输入关键字“七夕礼物”进行搜索时,发现网址中 q 的参数值即为所键入的关键字“七夕礼物”,如下图所示:

网址构成分析
因此可以使用以下方式构造网址:

q_value = "七夕礼物"
url = "https://s.taobao.com/search?q={}imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20210802&ie=utf8&bcoffset=5&p4ppushleft=2%2C48&ntoffset=5&s=44".format(q_value)

虽然也可以直接复制网址,但是这种方法的弊端在于,每次想要爬取其他类别的商品时,都需要重新打开网页复制网址;而利用 q_value 变量构造网址,当需要获取其他品类商品时仅需要修改 q_value 变量,例如要爬取关键字“七夕礼物送男友”,只需要做如下修改:

q_value = "七夕礼物送男友"

🕸? 网页结构分析

使用浏览器“开发者工具”,观察网页结构,可以看出商品的信息都是在 <script> 中,

网页结构
因此,首先使用 requests 库请求网页内容,需要注意的是,在请求页面信息时,需要构造请求头中的 cookieuser-agent 信息,否则并不会得到有效响应,获取 cookieuser-agent 信息需要在浏览器“开发者工具”中的网络标签下单击当前请求页面(如果网络标签下没有当前请求的页面,需要刷新后才可以显示),在标头选项卡中找到请求标头cookieuser-agent 值并复制,按照以下方式构造请求头:

headers = {
	# 将user-agent值,替换为刚刚复制的user-agent值
    "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36 Edg/92.0.902.62",
    # 将cookie值,替换为刚刚复制的cookie值
    "cookie":"...JSESSIONID=4990DB1E8783DF90266F5159209F8E3A"
}

下图显示了获取 cookie 值的示例(获取 user-agent 值的方式类似,只需在标头选项卡中找到请求标头user-agent 值):

构造cookie信息

得到响应网页后,需要使用 BeautifulSoup4 与正则表达库 re 解析网页,获取商品信息:

import re
import  requests
from bs4 import BeautifulSoup

# 请求网页
response = requests.get(url,headers =headers)
response.raise_for_status()
response.encoding = 'utf-8'
# 解析网页
soup = BeautifulSoup(response.text, 'html.parser')
results = soup.find_all('script')
information = str(results[7])

# 获取商品标题
raw_title = re.findall(r'"raw_title":"(.*?)"', information)
# 获取商品价格
view_price = re.findall(r'"view_price":"(.*?)"', information)
# 获取购买人数
view_sales = re.findall(r'"view_sales":"(.*?)"', information)
# 获取发货地址
item_loc = re.findall(r'"item_loc":"(.*?)"', information)
# 获取店铺名
nick = re.findall(r'"nick":"(.*?)"', information)
# 获取详情页地址
detail_url = re.findall(r'"detail_url":"(.*?)"', information)
# 获取封面图片地址
pic_url = re.findall(r'"pic_url":"(.*?)"', information)

需要注意的是,由于一开始使用 utf-8 方式解码网页,并不能解码 Unicode,因此打印详情页地址和封面图片地址会看到解码不正确的情况:

print(detail_url[4])
# //detail.tmall.com/item.htm?id\u003d628777347316\u0026ns\u003d1\u0026abbucket\u003d17

因此需要使用以下方式进行正确解码:

decodeunichars = detail_url[4].encode('utf-8').decode('unicode-escape')
print(decodeunichars)
# //detail.tmall.com/item.htm?id=628777347316&ns=1&abbucket=17

🕸? 将数据写入csv文件中

为了将数据写入 csv 文件中,首先创建 csv 文件并写入标头:

#创建存储csv文件存储数据
file = open('gift.csv', "w", encoding="utf-8-sig",newline='')
csv_head = csv.writer(file)
#表头
header = ['raw_title','view_price','view_sales','salary','item_loc','nick','detail_url','pic_url']
csv_head.writerow(header)
file.close()

然后,由于英文逗号(",")表示单元格的切换,因此需要将获取的数据经过预处理:

def precess(item):
    return item.replace(',', ' ')

最后将预处理数据后,将数据写入 csv 文件中:

for i in range(len(raw_title)):
    with open('gift.csv', 'a+', encoding='utf-8-sig') as f:
        f.write(precess(raw_title[i]) + ',' 
                + precess(view_price[i]) + ',' 
                + precess(view_sales[i]) + ','  
                + precess(item_loc[i]) +',' 
                + precess(nick[i]) + ','
                + precess(detail_url[i]) + ','
                + precess(pic_url[i]) + '\n')

🕸? 通过观察页面链接,爬取更多页面

通过查看第2页以及第3页,网址:

https://s.taobao.com/search?q=七夕礼物imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20210805&ie=utf8&bcoffset=1&ntoffset=1&p4ppushleft=2%2C48&s=44
https://s.taobao.com/search?q=七夕礼物&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20210805&ie=utf8&bcoffset=1&ntoffset=1&p4ppushleft=2%2C48&s=88

可以看到,网址的不同仅在于第二页的 s 的参数值为 44,而第三页 s 的参数值为 88,结合可以每页有 44 个商品,因此可以使用以下方式构造爬取20页商品:

url_pattern = "https://s.taobao.com/search?q={}&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20210805&ie=utf8&bcoffset=1&ntoffset=1&p4ppushleft=2%2C48&s={}"
for i in range(20):
    url = url_pattern.format(q, i*44)

🕸? 爬虫程序完整代码

import re
import  requests
import time
from bs4 import BeautifulSoup
import csv
import os

q = "七夕礼物"
url_pattern = "https://s.taobao.com/search?q={}&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20210805&ie=utf8&bcoffset=2&ntoffset=2&p4ppushleft=2%2C48&s={}"

headers = {
    "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36 Edg/92.0.902.62",
    # cookie值替换为使用上述方式获取的cookie值
    "cookie":"..."
}
    
def analysis(item,results):
    pattern = re.compile(item, re.I|re.M)
    result_list = pattern.findall(results)
    return result_list

def analysis_url(item, results):
    pattern = re.compile(item, re.I|re.M)
    result_list = pattern.findall(results)
    for i in range(len(result_list)):
        result_list[i] = result_list[i].encode('utf-8').decode('unicode-escape')
    return result_list


def precess(item):
    return item.replace(',', ' ')

# 创建csv文件
if not os.path.exists("gift.csv"):
    file = open('gift.csv', "w", encoding="utf-8-sig",newline='')
    csv_head = csv.writer(file)
    #表头
    header = ['raw_title','view_price','view_sales','salary','item_loc','nick','detail_url','pic_url']
    csv_head.writerow(header)
    file.close()

for i in range(100):
    #增加时延防止反爬虫
    time.sleep(25)
    url = url_pattern.format(q, i*44)
    response = requests.get(url=url, headers=headers)
    
    #声明网页编码方式,需要根据具体网页响应情况
    response.encoding = 'utf-8'
    response.raise_for_status()
    soup = BeautifulSoup(response.text, 'html.parser')

    results = soup.find_all('script')
    information = str(results[7])

    # 获取所有的商品信息,由于有些购买人数为空白,导致返回空值,因此添加异常处理
    all_goods = analysis(r'"raw_title":"(.*?)"shopLink"', information)
    for good in all_goods:
        
        # 获取商品标题
        raw_title = analysis(r'(.*?)","pic_url"', good)
        if not raw_title:
            raw_title.append('未命名')
        # 获取商品价格
        view_price = analysis(r'"view_price":"(.*?)"', good)
        if not view_price:
            view_price.append('0.00')
        # 获取购买人数,由于有些购买人数为空白,导致返回空值,因此添加异常处理
        view_sales = analysis(r'"view_sales":"(.*?)"', good)
        #print(view_sales)
        if not view_sales:
            view_sales.append('0人付款')
        # 获取发货地址
        item_loc = analysis(r'"item_loc":"(.*?)"', good)
        if not item_loc:
            item_loc.append('未知地址')
        # 获取店铺名
        nick = analysis(r'"nick":"(.*?)"', good)
        if not nick:
            nick.append('未知店铺')
        # 获取详情页地址
        detail_url = analysis_url(r'"detail_url":"(.*?)"', good)
        if not detail_url:
            detail_url.append('无详情页')
        # 获取封面图片地址
        pic_url = analysis_url(r'"pic_url":"(.*?)"', good)
        if not pic_url:
            pic_url.append('无封面')
        with open('gift.csv', 'a+', encoding='utf-8-sig') as f:
            f.write(precess(raw_title[0]) + ',' 
                    + precess(view_price[0]) + ',' 
                    + precess(view_sales[0]) + ',' 
                    + precess(item_loc[0]) +',' 
                    + precess(nick[0]) + ','
                    + precess(detail_url[0]) + ','
                    + precess(pic_url[0]) + '\n')

🕸? 爬取数据结果

爬取数据展示

数据分析及可视化

可能很多朋友(并非)是为了学习技术才点击进来的,完(shun)全(bian)是求知若渴的想知道要送男朋友/女朋友什么礼物,别着急,大家最关注的部分来了。
接下来使用词云可视化分析,分别考虑包含销量与不包含销量两种情况。

🎁 七夕礼物清单

不考虑销量时:

from os import path
from PIL import Image
import matplotlib.pyplot as plt
import jieba
from wordcloud import WordCloud, STOPWORDS
import pandas as pd
import matplotlib.ticker as ticker
import numpy as np
import math
import re

df = pd.read_csv('gift.csv', encoding='utf-8-sig',usecols=['raw_title','view_price','view_sales','salary','item_loc','nick','detail_url','pic_url'])

raw_title_list = df['raw_title'].values
raw_title = ','.join(raw_title_list)
with open('text.txt','a+') as f:
    f.writelines(raw_title)

###当前文件路径
d = path.dirname(__file__)

# Read the whole text.
file = open(path.join(d, 'text.txt')).read()
##进行分词
#停用词,去除修饰性的词
stopwords = ["七夕","七夕情人节","情人节","男友","女友","男生","女生","女朋友","男朋友","礼物","生日礼物","创意","实用","朋友","男士","老婆","老公","直营","闺蜜","结婚","送给"]
text_split = jieba.cut(file)  # 未去掉停用词的分词结果   list类型

#去掉停用词的分词结果  list类型
text_split_no = []
for word in text_split:
    if word not in stopwords:
        text_split_no.append(word)
#print(text_split_no)

text =' '.join(text_split_no)
#背景图片
picture_mask = np.array(Image.open(path.join(d, "beijing.jpg")))
stopwords = set(STOPWORDS)
stopwords.add("said")
wc = WordCloud(  
    #设置字体,指定字体路径
    font_path=r'C:\Windows\Fonts\simsun.ttc',
    background_color="white",   
    max_words=4000,   
    mask=picture_mask,  
    stopwords=stopwords)  
# 生成词云
wc.generate(text)

# 存储图片
wc.to_file(path.join(d, "result.jpg"))

可视化
接下来考虑销量:

def get_sales(item):
    tmp = item[:-3]
    if '万' in tmp:
        tmp = tmp.replace('万','0000').replace('.','')
    if '+' in tmp:
        tmp = tmp.replace('+','')
    tmp = int(tmp)
    tmp = tmp / 100.0
    if tmp <= 0:
        tmp = 0
    tmp = round(tmp)
    return tmp
    
raw_title_list = df['raw_title'].values
view_sales_list = df['view_sales'].values
for i in range(len(raw_title_list)):
    for j in range(get_sales(view_sales_list[i])):
        with open('text.txt','a+') as f:
            f.writelines(raw_title_list[i]+',')
# 其余代码不再赘述
"""
...
"""

请添加图片描述

可以看到差别还是较为明显的,最后将分词结果,进行排序,手动去除无效词后,归类整理出排名前15的礼物清单:

gift = {}
for i in text_split_no:
	if gift.get(i,0):
		gift[i] += 1
	else:
		gift[i] = 1
sorted_gift = sorted(gift.items(), key=lambda x:x[1],reverse=True)

??礼物清单??

玩偶/公仔/毛绒玩具/抱抱熊
糖果
项链
巧克力
相册/纪念册
零食/小吃
手链/手镯/镯子
玫瑰
吊坠
小夜灯
音乐盒/八音盒
戒指/对戒
口红
手绳/红绳
耳钉

👧 送女朋友礼物清单

以同样的方法,将关键字改为“女友+礼物”,可以得到??送女朋友礼物清单??:

小夜灯
相册/纪念册/相框
刻字类礼物
八音盒
项链/手链/手镯/镯子
口红
手表
包
水晶鞋
玩偶

👦 送男朋友礼物清单

最后,将关键字改为“男友+礼物”,可以得到??送男朋友礼物清单??:

可乐刻字
相册/纪念册/相框
花束
手办
摆件
钥匙扣
木刻画
情书
刺绣
篮球

可以看出,送女朋友和男朋友的礼物还是有一些差别的。
当然,和主管感觉上有很些差异的原因可能在于,很多商品的标题太过创意,完全不包含商品。

下一步计划

下一步的工作包括:

  1. 获取商品的评价信息,将购买者的评论信息也融合到计算权重中去,根据购买者的评价对商品排序进行修正,例如可能去除一些华而不实的“智商税”产品,同时可能得到一些小众好评的商品。
  2. 利用深度学习相关技术,识别图片中商品,用以解决一些商品标题及商品图片文字中完全不包含商品名的情况,让我们明白标题为《生日礼物女生七夕情人节给闺蜜送女友朋友送给女孩的实用小高级感》的商品到底卖的是什么?

写在最后

当然,本文仅做分析之用,结果也仅供参考,如果清单里没有令你心仪的礼物,也可以选择红包或者清空购物车的方式。无论送女朋友/男朋友什么礼物,传达自己的??心意??最重要了。

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-08-10 13:22:40  更:2021-08-10 13:22:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 14:37:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码