python爬取天猫评论并制作词云, 用Scrapy+ selenium实现

6 篇文章 0 订阅
4 篇文章 0 订阅

前一段时间爬取了天猫某些商品的评论数据并进行轻度处理,今天就跟大家聊聊见解吧!

话不多说直接开始:

大家都知道淘宝天猫作为国内最大的电商平台之一, 它对网站的加工是极好的,网站的配置也是非常完美的,其中就包括了反爬虫的设计. 淘宝的登录页面是可以检测selenium操作的,所以用selenium模拟登录是不可行的,只要你用selenium模拟登录不管怎么样都是失败的.但是我们可以带cookie直接登录的,当然这个很简单用requests带cookie访问就OK了,那么我们应该怎么用Scrapy + selenium模拟浏览器拿到数据呢?很简单

首先我们来说怎么登录到淘宝,其实我们Scrapy直接请求需要爬取的店铺的网址,当然不要先模拟登录,因为铁定被查到,然后禁止.当我们直接请求的时候回得到这样的页面: 直接转到商品页面,会弹出一个二维码,这个时候你可以扫码登录,或者点掉,并不影响整个爬取.

当然今天我又看了一下,cookie都不用带直接就可以进去拿数据了,当然我说的是selenium模拟浏览器的方法.

还有就是聊聊下一个点, 我们进入页面看到的是这样的页面

初始页面是拿不到评价数据的, 我们只能拿到商品信息, 商品详情, 以及销售量等的信息, 这也就是我们为什么要用selenium的原因, 我们可以用selenium模拟浏览器点击页面, 跳转到评价页面,然后模拟滚动条滚动, 并模拟点击下一页以便拿到所有的数据

现在来展示一下代码:

这只是selenium模拟浏览器在Scrapy中的用法,现在咱们来解析一下代码:

class SeleniumMiddlewares(object):
    def __init__(self):
        self.options = Options()
        # self.options.add_argument('-headless')
        初始化Chrome驱动以便驱动谷歌浏览器,当然你也可以用firbox火狐浏览器, 这个根据你的驱动下载位置填写
        self.browser = webdriver.Chrome(executable_path=r"E:\爬虫\ziliao\chromedriver",
                                        chrome_options=self.options)

    def process_request(self, request, spider):
        page参数是根据spider中请求带来的参数,当参数为一的时候点击累积评价进去评价页面
        if int(request.meta["page"]) == 1:
            self.browser.get(request.url)
            time.sleep(5)
            for y in range(10):
                模拟滚动条滚动,一次滚动220px, 一个滚动10次
                self.browser.execute_script("window.scrollBy(0,220)")
                time.sleep(0.2)
            找到累积评价的标签并点击
            pages = self.browser.find_element_by_xpath('//li/a[@href="#J_Reviews"]')
            pages.click()
            time.sleep(5)
            返回页面相应给spider
            return HtmlResponse(url=self.browser.current_url,body=self.browser.page_source,request=request,encoding="utf-8")
        当带来的参数为2时,进行翻页点击操作
        if int(request.meta["page"]) == 2:
            for y in range(20):
                模拟滚动20次,每次200px
                self.browser.execute_script("window.scrollBy(0,200)")
                time.sleep(0.2)
            找到下一页标签, 并点击
            pages = self.browser.find_element_by_link_text("下一页>>")
            self.browser.execute_script("arguments[0].click();", pages)
            # pages.click()
            return HtmlResponse(url=self.browser.current_url, body=self.browser.page_source, request=request,encoding="utf-8")

其实整个爬虫项目的难点就在于这个模拟点击下一页了,当然也可以不用selenium,那么你就去分析接口吧, 也不难,不过不适用通用爬虫, 因为每个网页的接口都是不一样的.言归正传,下面来看看spider的代码吧!因为很简单我就带着大家过一遍就行了.

其实我们做的这个只是最简单的爬取一个页面的需求,毕竟是给大家分享的,所以也不需要太难,原理都是一样,大家会了以后自己做就行了.

而我们这个简单的爬取因为没有网页嵌套所以我们就只需要拿到selenium传回来的数据进行解析就好了, 我们也就用xpath拿到了买家评论, 店家回复, 买家会员等级以及最佳评论这四个, 当然你也可以拿到商品的各种数据, 原理是一样的,这里我就不再一一操作了.话不多说看代码:

class EveSpider(scrapy.Spider):
    name = 'eve'
    # allowed_domains = ['detail.tmall.com']

    def start_requests(self):
        改变初始请求,根据自己的心意来
        base_url = "https://detail.tmall.com/item.htm?spm=a220m.1000858.1000725.1.10071a2e3E99KN&id=576412995625&skuId=3959303342392&areaId=410881&standard=1&user_id=533497499&cat_id=50029231&is_b=1&rn=297f6b58b52879a5dd9d1a7b4d628f85"
        yield Request(url=base_url, callback=self.parse, dont_filter=True, meta={"page":"1"})

    def parse(self, response):
        进行解析
        item = TmallItem()
        tr_list = response.xpath('//div[@class="rate-grid"]/table/tbody/tr').extract()
        for tr in tr_list:
            html = lxml.html.fromstring(tr)
            try:
                command = html.xpath('//div[@class="tm-rate-premiere"]/div[@class="tm-rate-content"]/div[@class="tm-rate-fulltxt"]/text()')[0]
            except:
                try:
                    command = html.xpath('//div[@class="tm-rate-content"]/div[@class="tm-rate-fulltxt"]/text()')[0]
                except:
                    command = "此用户暂无评价"
            times = html.xpath('//div[@class="tm-rate-date"]/text()')[0]
            try:
                explain = html.xpath('//div[@class="tm-rate-reply"]/div[@class="tm-rate-fulltxt"]/text()')[0]
            except:
                explain = "暂无店家解释"
            try:
                grade = html.xpath('//div[@class="rate-user-grade"]/p/text()')[0]
            except:
                grade = "普通会员"
            try:
                append_command = html.xpath('//div[@class="tm-rate-append"]/div[@class="tm-rate-content"]/div[@class="tm-rate-fulltxt"]/text()')[0]
            except:
                append_command = "暂无追加评论"
            item["command"] = command
            item["times"] = times
            item["explain"] = explain
            item["grade"] = grade
            item["append_command"] = append_command
            yield item

        yield Request(url="http://www.baidu.com",callback=self.parse,meta={"page": 2"}, dont_filter=True)

 

其实整个项目并不难,主要就是selenium的应用, 可以解决很多问题, 就是速度会很慢.

所以这些就不说了, 来看看咱们的切词, 得词云的过程

现在大家迫不及待了吧,那就直接上代码

想必大家看着有点蒙圈了吧,我来给大家分析一下吧

import pandas as pd
import jieba.analyse
import pymongo
import matplotlib.pyplot as plt
from wordcloud import WordCloud, ImageColorGenerator

# 导入数据
首先导入你爬取的数据, 可以是txt文档, csv文档, 数据库

mg = pymongo.MongoClient('localhost', 27017).mine.tianmao
用pandas进行处理
data = pd.DataFrame(list(mg.find()))
拿到所有的评论内容
pl = data[:]["content"]
pl_str = ""
拼接成字符串
for i in pl:
    pl_str += i
# 添加特定停止词
删掉一些无用的平时的修饰词,如'的''啦'等
jieba.analyse.set_stop_words("stop_words.txt")


# 基于TF-IDF算法进行关键词抽取
用TF-IDE算法对字符串进行切词, 得到所有的关键词
keywords = jieba.analyse.extract_tags(pl_str, topK=300,withWeight=True, allowPOS=('ns', 'n', 'vn', 'v'))
#   'ns', 'n', 'vn', 'v'   即仅提取地名、名词、动名词、动词


# 基于TextRank算法进行关键词抽取
# keywords = jieba.analyse.textrank(pl_str, topK=10, withWeight=True, allowPOS=('ns', 'n', 'vn', 'v'))

print(len(keywords))

# 词云图生成

cloud_con = ''

for k, v in keywords:
    cloud_con += (k+"/")*(int(v*1000))


# bg_image = plt.imread('er.jpg')
#云图属性设置
wc = WordCloud(font_path="miaowu.ttf",     设置字体
               background_color='white',    背景
               width=800,                   宽度
               height=600,                 高度
               # mask=bg_image,
               max_font_size=166,          最大字体大小
               min_font_size=16,           最小字体的尺度
               max_words=1000,             词云容纳词量
               mode='RGBA',
               # scale=2,
               # colormap='pink',
               collocations=False,
               random_state=30
               )
wc.generate(cloud_con)
# 设置字体颜色跟随背景变化
# bg_color = ImageColorGenerator(bg_image)
# wc.recolor(color_func=bg_color)
wc.to_file("word___cloud.png")
plt.figure()
plt.imshow(wc)
# plt.axis("off")
plt.show()

最后就来看看我们的辛苦结果吧

感觉怎么样, 都还喜欢嘛?有什么问题可以在下面评论哦! 我会在线上解答问题哦! 项目我也放到资源里了, 需要的可以去下载哦!

最后再加一句, 欢迎来评论交流哦!

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值