码迷,mamicode.com
首页 > 其他好文 > 详细

充气娃娃什么感觉?

时间:2019-09-25 00:52:22      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:sts   mode   atp   ctp   otl   商品   json   call   show   

ps:本文参考“裸睡的猪”公众号。

 

 本文中所用的到第三方库有:

requests   jieba   numpy    Pillow    wordcloud    matplotlib

前言:

基于很多人没有体验过充气娃娃是什么感觉,但是又很好奇,所以希望通过爬虫+数据分析的方式直观而真实的告诉大家(下图为成品图)

技术图片

 

 

一、技术方案

1、分析狗东评论数据的请求url

2、使用requests库来抓取评论内容

3、使用词云做数据展示

二、技术实现

1、分析并获取商品评论的接口

第一步:打开狗东的商品页,搜索你想研究的商品。我们这里直接搜索“充气娃娃”,然后进入第一个店铺。

 

第二步:我们在页面中鼠标右键选择检查(或F12)调出浏览器的调试窗口。

技术图片

 

 

第三步:调出浏览器后点击评论按钮使其加载数据,然后我们点击network查看数据。

技术图片

 

 技术图片

 

 第四部:点击Headers,获取评论的接口

技术图片

 

 

经过上面的步骤,我们就轻松的获取到了评论的请求接口。

 

2、爬取数据

拿到评论数据接口url之后,我们就可以开始写代码抓取数据了。一般我们会先尝试抓取一条数据,成功之后,我们再去分析如何实现大量抓取。

import requests


def spider_comment():
    """爬取狗东评论数据"""
    kv = {Referer: https://item.jd.com/1070129528.html,
          Sec-Fetch-Mode: no-cors,
          User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36}

    url = https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98vv9087&productId=1070129528&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1
    try:
        result = requests.get(url, headers=kv)
        result.raise_for_status()  # 返回状态码。如果返回4XX或者5XX直接执行except
        print(result.text)
    except Exception as e:
        print(e)

if __name__ == __main__:
    spider_comment()

获取到如图数据:

技术图片

 

 3、数据提取

我们对爬取的数据分析发现,此数据为jsonp跨域请求返回的json结果,所以我们只要把前面的fetchJSON_comment98vv9087(和最后的)去掉就拿到json数据了。

将json数据复制到json格式化工具中或者在Chrome浏览器调试窗口点击Preview也可以看到,json数据中有一个key为comments的值便是我们想要的评论数据。

我们再对comments值进行分析发现是一个有多条数据的列表,而列表里的每一项就是每个评论对象,包含了评论的内容,时间,id,评价来源等等信息,而其中的content字段便是我们在页面看到的用户评价内容。

 

技术图片

 

 

import json

import requests


def spider_comment():
    """爬取狗东评论数据"""
    kv = {Referer: https://item.jd.com/1070129528.html,
          Sec-Fetch-Mode: no-cors,
          User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36}

    url = https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98vv9087&productId=1070129528&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1
    try:
        result = requests.get(url, headers=kv)
        result.raise_for_status()
        result_json_str = result.text[26:-2]  # json字符串
        result_dict = json.loads(result_json_str)  # 将json转换为字典
        result_json_comments = result_dict[comments]  # 经过分析,发现评论都在‘comments‘,返回列表套字典
        for i in result_json_comments:  # 真正的评论在‘content
            print(i[content])
    except Exception as e:
        print(e)

if __name__ == __main__:
    spider_comment()

4.数据保存

数据提取后我们需要将他们保存起来,一般保存数据的格式主要有:文件、数据库、内存这三大类。今天我们就将数据保存为txt文件格式,因为操作文件相对简单同时也能满足我们的后续数据分析的需求。

import json
import os
import random
import time

import requests

comment_file_path = ‘jd_comment.txt‘


def spider_comment():
"""爬取狗东评论数据"""
kv = {‘Referer‘: ‘https://item.jd.com/1070129528.html‘,
‘Sec-Fetch-Mode‘: ‘no-cors‘,
‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36‘}

url = ‘https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98vv9086&productId=1070129528&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1‘
try:
result = requests.get(url, headers=kv)
result.raise_for_status()
result_json_str = result.text[26:-2] # json字符串
result_dict = json.loads(result_json_str) # 将json转换为字典
result_json_comments = result_dict[‘comments‘] # 经过分析,发现评论都在‘comments‘,返回列表套字典
for i in result_json_comments: # 真正的评论在‘content‘
with open(comment_file_path, ‘a+‘, encoding=‘utf-8‘) as f:
f.write(i[‘content‘] + ‘\n‘)
except Exception as e:
print(e)

if __name__ == ‘__main__‘:
spider_comment()

5.批量爬取

我们刚刚完成一页数据爬取、提取、保存之后,我们来研究一下如何批量抓取?

做过web的同学可能知道,有一项功能是我们必须要做的,那便是分页。何为分页?为何要做分页?

我们在浏览很多网页的时候常常看到“下一页”这样的字眼,其实这就是使用了分页技术,因为向用户展示数据时不可能把所有的数据一次性展示,所以采用分页技术,一页一页的展示出来。

让我们再回到最开始的加载评论数据的url:

https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98vv9087&productId=1070129528&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1

我们可以看到链接里面有两个参数page=0&pageSize=10,page表示当前的页数,pageSize表示每页多少条,那这两个数据直接去数据库limit数据。

老司机一眼便可以看出这就是分页的参数,但是有同学会说:如果我是老司机还干嘛看你的文章?所以我教大家如何来找到这个分页参数

回到某东的商品页,我们将评价页面拉到最底下,发现有分页的按钮,然后我们在调试窗口清空之前的请求记录。

技术图片

 

 清空之前的请求记录之后,我们点击上图红框分页按钮的数字2,代表这第二页,然后复制第一条评价去调试窗口搜索,最后找到请求链接。

和上面的步骤一样。技术图片

 

 然后我们比较第一页评价与第二页评价的url有何区别,可以很容易发下只有page不同。

这里也就验证了猜想:page表示当前的页数,pageSize表示每页多少条。而且我们还能得出另一个结论:第一个page=0,第二页page=1 然后依次往后。有同学会问:为什么第一页不是1,而是0,因为在数据库中一般的都是从0开始计数,编程行业很多数组列表都是从0开始计数。

好了,知道分页规律之后,我们只要在每次请求时将page参数递增不就可以批量抓取了吗?我们来写代码吧!

import json
import os
import random
import time

import requests

comment_file_path = jd_comment.txt


def spider_comment(page):
    """爬取狗东评论数据"""
    kv = {Referer: https://item.jd.com/1070129528.html,
          Sec-Fetch-Mode: no-cors,
          User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36}

    url = https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98vv9086&productId=1070129528&score=0&sortType=5&page=%s&pageSize=10&isShadowSku=0&fold=1 % page
    try:
        result = requests.get(url, headers=kv)
        result.raise_for_status()
        result_json_str = result.text[26:-2]  # json字符串
        result_dict = json.loads(result_json_str)  # 将json转换为字典
        result_json_comments = result_dict[comments]   # 经过分析,发现评论都在‘comments‘,返回列表套字典
        for i in result_json_comments:  # 真正的评论在‘content‘
            with open(comment_file_path, a+, encoding=utf-8) as f:
                f.write(i[content] + \n)
    except Exception as e:
        print(e)


def batch_spider_comment():
    # 写入文件之前,先清空之前的数据
    if os.path.exists(comment_file_path):
        os.remove(comment_file_path)
    for i in range(100):
        spider_comment(i)
        # 模拟用户浏览,设置一个爬虫间隔,防止ip被封
        time.sleep(random.random() * 5)


if __name__ == __main__:
    batch_spider_comment()

6.数据清洗以及生成词云。

数据成功保存之后我们需要对数据进行分词清洗,对于分词我们使用著名的分词库jieba

import jieba
import numpy as np
from PIL import Image
from wordcloud import WordCloud
import matplotlib.pyplot as plt


comment_file_path = jd_comment.txt

def cut_word():
    ‘‘‘
    对数据分词
    :return: 分词后的数据
    ‘‘‘
    with open(comment_file_path, r, encoding=utf-8) as f:
        comment_txt = f.read()

        wordlist = jieba.cut(comment_txt, cut_all=True)
        word_str =  .join(wordlist)
        #print(word_str)
        return word_str


def create_word_cloud():
    """生成词云"""
    # 设置词云形状图片
    coloring = np.array(Image.open(wawa.jpg))
    # 设置词云一些配置,如字体,背景色,词云形状,大小
    wc = WordCloud(background_color=white, max_words=2000,mask=coloring, scale=4,
                   max_font_size=50, random_state=42, font_path=C:\Windows\Fonts\msyhbd.ttc)
    # 生成词云
    wc.generate(cut_word())

    # 在只设置mask情况下,会拥有一个图形形状的词云
    plt.imshow(wc, interpolation="bilinear")
    plt.axis(off)
    plt.figure()
    plt.show()



if __name__ == __main__:
    create_word_cloud()

注意:font_path是选择字体的路径,如果不设置默认字体可能不支持中文,猪哥选择的是Mac系统自带的宋体字!

最终结果:

技术图片

 

充气娃娃什么感觉?

标签:sts   mode   atp   ctp   otl   商品   json   call   show   

原文地址:https://www.cnblogs.com/huiyichanmian/p/11581980.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!