目录

  • 简介
  • 网页展示
  • 阿里云的反爬策略
  • 我的反-反爬策略
  • 代码实现
    • items类的定义
    • 爬虫规则的定义
      • 定义start_requests函数
      • 定义回调函数parse()
    • settings.py的参数修改
  • 结果展示
  • 词云图绘制
  • 小结与感想

简介

近日因为公司业务需要,领导要求我批量获取一款天猫商城上的商品链接下的评论。虽然我已有超过一年的爬虫实战经验,但是一想到我即将面对的是“阿里云”这一BUG级怪物,头皮不由自主地发麻了。但是秉着“万物皆可爬”的信念,我还是硬着头皮上了。

网页展示

我需要获取的网页链接为天猫商城。
先来看看评论区的模样吧。


正如大家所熟知的,评论栏目十分工整,所有评论都整齐地摆放在了网页当中,而页面末尾还有翻页按钮。一切还似乎是简单的模样。
然而,爬虫界里有一句话可谓是“至理箴言”——你看得到不一定你就能爬得到。这不,当我打开浏览器监听器时就发现了天猫商品的网页采取的都是异步请求方式获得的,评论区的都内容都停放在了类似于
https://rate.tmall.com/list_detail_rate.htm?itemId=537259015354&spuId=694941313&sellerId=2386968451&order=3&currentPage=2&append=0&content=1&tagId=&posi=&picture=&groupId=&ua=098%23E1hvS9vovLIvUvCkvvvvvjiPRFzpsjnmRLFw0jrCPmPZlj3CnLMpljYWn2LwQj3bRphvCvvvvvmCvpvZz2staosNznswUGrfYgsw1aAv7IVrvpvEvCB%2FvNsGv2s22QhvCvvvMMGCvpvVvmvvvhCvKphv8vvvvvCvpvvvvvv2vhCvCjQvvvWvphvW9pvvvQCvpvs9vvv2vhCv2RmEvpvVmvvC9jamuphvmvvv9bcWRGhImphvLvCbXvvjna21Q8oaWLEc34z%2BFfmtEpcUTUoXKFwFxT7YK4vTHkGVqwzaiLu18vmYiR0n%2BbyDCw2IAXZTKFEw9Exrz8TJEcq9afknnbvtvpvhvvvvv8wCvvpvvUmm3QhvCvvhvvmrvpvpjvkJ9wjCvmvIFfwznHVt6OhCvvswMHna3nMwznQY3DItvpvhvvvvvUhCvvswNHBwEaMwzns%2FblItvpvhvvvvv86Cvvyv2h7n1GwvzWy%3D&needFold=0&_ksTS=1561438169812_1139&callback=jsonp1140
这样的链接当中。
可以注意到,链接当中包含着一个currentPage字段,只要通过更改currentPage的值即可实现翻页的效果。


上图为评论区内容的停放方式。实话说,到目前为止,我还没有体会到阿里云的强大之处到底在哪,根据个人经验,我仍然觉得只要听过递归算法实现翻页、逐个获取就可以完成老板的任务。然而,不到最后一刻真的不能轻易放松啊。

阿里云的反爬策略

通常来讲,如果网站想要反爬,它们通常会从访问者的访问频率入手,只要识别到某个IP发出的请求在某一时间段内极度频繁网站便会认定(如果真的需要反爬的话)该访问者为不友好客户,将该IP封锁请求一段时间。
然而阿里云的高明之处在于它压根不需要设置反爬就可以屏蔽掉大部分不友好访问者了。至于原因如何,请看如下:
我在pycharm terminal当中利用scrapy shell对需要访问的网址进行测试

> scrapy shell "https://rate.tmall.com/list_detail_rate.htm?itemId=537259015354&spuId=694941313&sellerId=2386968451&order=3&currentPage=2&append=0&content=1&tagId=&posi=&picture=&groupId=&ua=098%23E1hvS9vovLIvUvCkvvvvvjiPRFzpsjnmRLFw0jrCPmPZlj3CnLMpljYWn2LwQj3bRphvCvvvvvmCvpvZz2staosNznswUGrfYgsw1aAv7IVrvpvEvCB%2FvNsGv2s22QhvCvvvMMGCvpvVvmvvvhCvKphv8vvvvvCvpvvvvvv2vhCvCjQvvvWvphvW9pvvvQCvpvs9vvv2vhCv2RmEvpvVmvvC9jamuphvmvvv9bcWRGhImphvLvCbXvvjna21Q8oaWLEc34z%2BFfmtEpcUTUoXKFwFxT7YK4vTHkGVqwzaiLu18vmYiR0n%2BbyDCw2IAXZTKFEw9Exrz8TJEcq9afknnbvtvpvhvvvvv8wCvvpvvUmm3QhvCvvhvvmrvpvpjvkJ9wjCvmvIFfwznHVt6OhCvvswMHna3nMwznQY3DItvpvhvvvvvUhCvvswNHBwEaMwzns%2FblItvpvhvvvvv86Cvvyv2h7n1GwvzWy%3D&needFold=0&_ksTS=1561438169812_1139&callback=jsonp1140"


在点击运行shell命令以后,程序实际上在不停地重定向,以至于最后请求得到的response.body为


response.body所指的链接包含了“login”一词,也就是说我们每一次访问都意味着需要登录一次个人密码,更何况,经本人验证,密码验证通过以后普通用户也无权查看网页内容。所以说,马爸爸能有今日的成就真的不是靠吹牛吹出来的。

我的反-反爬策略

正当我毫无头绪,准备等着去老总办公室领便当之时,我心血来潮地用火狐浏览器再次打开商品链接。正是这一次无心之举让我看到了曙光,因为不同于Google Chrome的浏览器监听,Firefox浏览器监听还给出了每个链接各自的请求cookies以及响应cookies。

而有了网页cookies的加持,代码实现自然便廓然开朗了。

代码实现

scrapy的原理不多说,我的工作包括:在spider模块中定义爬取规则、在items模块定义所需信息以及在settings.py文件设置请求参数。

items类的定义

这一部分可以结合自身工作需要进行定义,不过建议初学者尽可能多地抓取信息,这样有利于对HTML的理解的长进以及后续爬虫能力的进步。

class TmallItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()init_comment = scrapy.Field()  # 首次评论内容init_images = scrapy.Field()  # 首次评论所发布的照片init_explanation = scrapy.Field()  # 首次评论时店家的回复append_comment = scrapy.Field()  # 追评内容append_images = scrapy.Field()  # 追评所发布的图片append_explanation = scrapy.Field()  # 追评回复category = scrapy.Field()  # 商品类型user = scrapy.Field()  # 用户名init_comment_date = scrapy.Field()  # 首次评论日期append_comment_date = scrapy.Field()  # 追评日期append_days = scrapy.Field()  # 追评日期距离收货日期的天数

爬虫规则的定义

本次爬虫逻辑为垂直式爬取,所以首先需要定义种子链接的形式。

name = 'jisu'
url = 'https://rate.tmall.com/list_detail_rate.htm?itemId=537259015354&spuId=694941313&sellerId=2386968451&' \'order=1&currentPage={page}&append=0&content=1&tagId=&posi=&picture=&groupId=&' \'ua=098%23E1hv0pvxvchvUvCkvvvvvjiPRFsOljlnP2F9tjYHPmP9ljnHnLqv6j3URFLhAj1U9phvHHiaLxF3zHi4w17gtssR7TC4NrGB' \'dphv219vhQ9wjVoKzYVtRkHL6OhCvv14cGJOEa1475PE7r%2FCvpvW7D%2FShUbw7Dis%2BtjN9phv2HiNsQ9bzHi4wTo2zsyCvvpvvvv' \'vkphvC9QvvOC0p4yCvv9vvUmljyONNbyCvmFMMQ2GS6vvtQvvvQCvpvoKvvv2vhCv2UhvvvWvphvWgvvvvQavpvQXmphvLv3fYpvjcRCl' \'dU9tK7ERiNLyzCyXfCuYiXVvVE6Fp%2B0x9W9OjLEc6acEKBm6NB3rQjcQ%2BulgEfk1DfesRk9cznsW1C0OwZFvgb2XrqpCvpvVvmvvv' \'hCv2QhvCvvvMMGtvpvhvvvvv8wCvvpvvUmm3QhvCvvhvvmCvpvW7D%2FjM0Lw7Di4XLLNdphvmpvhYUWOVvCpjOhCvCB47Twpc1147DiA' \'iKNG%2FHrz7IbNVLyCvvpvvvvvdphvmpvZL9nEop2nULyCvvpvvvvv&needFold=0' \'&_ksTS=1560657691879_1614&callback=jsonp1615'max_page = 8911

定义start_requests函数

要注意带上Firefox浏览器上的cookies.

    def start_requests(self):headers = {'User-Agent': USER_AGENT,}cookies = {'_l_g_': 'Ug==','_m_h5_tk': '7fc115a6218e184230f2576214bddb9d_1560939254163','_m_h5_tk_enc': '2234531bca3e65e82c1c4f1e84a9ff8e','_nk_': '\u5409\u7C73\u591A\u7EF4\u5947\u7231\u6570\u5206','_tb_token_': 'e3e6b1b159e7b','ck1': '','cna': 'fRQMFZNC9lUCAd0EIk1wBCP3','cookie1': 'AVJ0BAH4k1O+4H25j50cTLQqmMXYIJqxzI6MZPtNeyc=','cookie17': 'UU6oL/V0LlWJdQ==','cookie2': '1905c0ac2025ad5fa6bb8b0a0bbb3edc','csg': '2ab2dcee','enc': 'ooH8602regPsWM1QfY3QSxjCZFzz5o8Cc3HlKJU7zZGHQIGiyDbVU7tl3OLBBy8xg8tux6KZM6Dx6O7t+LoYFA==','hng': 'CN|zh-CN|CNY|156','isg': 'BCMjGH3segMKazekY19AtEN1sWdhBFppX-siTVWA5gJslEq23evtqnuGjqQ_Lw9S','l': 'bBr5SYxqv46OYL1BBOfZqQFf8hQTgIRVCkPP2PW6kICPOLCX5xhCWZh60VYWC31VZ1DyR3JceFJJB8TNpyCV.','lgc': '\u5409\u7C73\u591A\u7EF4\u5947\u7231\u6570\u5206','lid': '�米�维����','login': 'true','otherx': 'e=1&p=*&s=0&c=0&f=0&g=0&t=0','skt': '4445413dc568a647','t': '9d720f184875d4c25562b0a93e4f5996','tk_trace': '1','tracknick': '\u5409\u7C73\u591A\u7EF4\u5947\u7231\u6570\u5206','uc1': 'cookie16=Vq8l+KCLySLZMFWHxqs8fwqnEw==&cookie21=VFC/uZ9aiKCaj7AzMHh1&cookie15=UtASsssmOIJ0bQ==&''existShop=false&pas=0&cookie14=UoTaGOHiwTZ1YA==&tag=8&lng=zh_CN','uc3': 'vt3=F8dBy3kbj5HhJvR1epM=&id2=UU6oL/V0LlWJdQ==&nk2=3zMxvthgoDYtGUAVjC8HCg==&lg2=UIHiLt3xD8xYTw==','unb': '2696829666','uss': '','whl': '-1&0&0&0','x': '__ll=-1&_ato=0','x5sec': '7b22726174656d616e616765723b32223a223639643865623637336663346530323431313935653338623730383565''366237434d2f57702b6746454958316d346a64684b69364e686f4d4d6a59354e6a67794f5459324e6a7378227d'}for page in range(1, self.max_page + 1):yield scrapy.Request(self.url.format(page=page), headers=headers,cookies=cookies, callback=self.parse, dont_filter=True)

定义回调函数parse()

从监听器对链接的格式化显示可以看出,评论区的内容是以json格式储存在网站中的。因此,parse函数的关注焦点便是如何解析各网页的json内容。

    def parse(self, response):item = TmallItem()comments = re.findall('"rateList":(\[.*\]),"searchinfo"', response.text)comments = ''.join(comments)comments = json.loads(comments)for comment in comments:item['init_comment'] = comment['rateContent']item['init_images'] = comment['pics']item['init_explanation'] = comment['reply']item['category'] = ''.join(re.findall('颜色分类:(.*)', comment['auctionSku']))item['user'] = comment['displayUserNick']item['init_comment_date'] = ''.join(re.findall('\d{4}\D\d{1,2}\D\d{1,2}', comment['rateDate']))if comment['appendComment']:item['append_comment'] = comment['appendComment']['content']item['append_images'] = comment['appendComment']['pics']item['append_explanation'] = comment['appendComment']['reply']item['append_days'] = comment['appendComment']['days']try:item['append_comment_date'] = ''.join(re.findall('\d{4}\D\d{1,2}\D\d{1,2}',comment['appendComment']['commentTime']))finally:passelse:item['append_comment'] = Noneitem['append_images'] = Noneitem['append_explanation'] = Noneitem['append_comment_date'] = Noneitem['append_days'] = Noneyield item

以上工作全部都需要在spider类当中完成。

settings.py的参数修改

为了尽可能规避反爬机制的识别,我还在该文件中进行了以下操作。

ROBOTSTXT_OBEY = False
CONCURRENT_REQUESTS = 32
DOWNLOAD_DELAY = 1
CONCURRENT_REQUESTS_PER_DOMAIN = 16
CONCURRENT_REQUESTS_PER_IP = 16
FEED_EXPORT_ENCODING = 'GBK'  # 这里表示信息文本是GBK编码,避免了汉字数据输出时出现乱码的情况

至此,我的代码编写工作就算大功告成了。接下来便是需要等待输出结果了。

结果展示

经过长达10分钟的等待,我终于等到了最终结果。然而结果却没有我想象当中那般理想——超过八成的数据竟然是重!复!的!
实际上,我观察到我的程序在运行到一段时间过后,请求返回的数据都是一样的,这大概率是我用写死cookies这种饮鸩止渴的方式的锅了。不过考虑到我手头上至少能够拿到1992条数据,起码可以给老板交个差,所以也就没有继续深究下去了。

词云图绘制

这一部分的技术难度实话说并不高,唯一的痛点在于要用到的第三方模块又多又难安装,希望各位小伙伴们注意一下。

from wordcloud import WordCloud
import jieba
import pandas as pd
import matplotlib.pyplot as plt
from scipy.misc import imread

接下来的工作步骤,我已上传至我的主页,有兴趣了解的可前往下载(里面还有前述的爬虫代码哦!),我只展示结果:

小结与感想

至此我的工作就算完毕了,有收获,更有不足。我觉得这一次爬虫过后我最大的收获是自信,之前总想着阿里巴巴的网站防爬虫是多么多么的高级,自己一个区区本科学历小职员螳臂当车岂不是作死之举?而现在看来,一切困难只不过是只纸老虎,只要有恒心,就总有法子搞得定。
不过,我更在意的是这一编程工作所暴露出来的不足。尽管学习、实操Python爬虫已经超过一年了,但是还会时常发现自己对网络方面的知识有所欠缺。所获取的数据尚不完整就是最扎心的明证。但这恰恰是我敢于、乐意公开代码、分享经验的根本原因,我欢迎各路高手为我指点,相互切磋交流,一起进步!
祝福各位认真读完这篇文章的程序猿与程序媛们生活愉快,程序无BUG!

天猫商品评论爬虫攻略【基于scrapy框架】(内附词云图绘制代码)相关推荐

  1. Python 爬取蚂蜂窝旅游攻略 (+Scrapy框架+MySQL)

    前言:使用python+scrapy框架爬取蚂蜂窝旅游攻略 Git代码地址:https://github.com/qijingpei/mafengwo 获取代理IP地址的开源项目ProxyPool-m ...

  2. 爬虫实例:天猫商品评论爬虫

    最近被种草SK-II,本着学工科的严谨态度,决定用数据说话 爬取数据 参数解析 itemId是商品ID, sellerId 是卖家ID, currentPage是当前页码,目标url是https:// ...

  3. 基于Scrapy框架的Python新闻爬虫

    概述 该项目是基于Scrapy框架的Python新闻爬虫,能够爬取网易,搜狐,凤凰和澎湃网站上的新闻,将标题,内容,评论,时间等内容整理并保存到本地 详细 代码下载:http://www.demoda ...

  4. python新闻爬虫系统的功能_基于Scrapy框架的Python新闻爬虫

    一.开发背景 Python作为数据处理方面的一把好手,近年来的热度不断增长.网络爬虫可以说是Python最具代表性的应用之一,那么通过网络爬虫来学习Python以及网络和数据处理的相关内容可以说是再合 ...

  5. Python爬虫实战之二 - 基于Scrapy框架抓取Boss直聘的招聘信息

    Python爬虫实战之三 - 基于Scrapy框架抓取Boss直聘的招聘信息 ---------------readme--------------- 简介:本人产品汪一枚,Python自学数月,对于 ...

  6. 词云分析——基于Python对天猫商品评论进行词云分析

    文章目录 0 引言 1 准备工作 2 主程序 3 分析与改进 4 可能出现的报错及解决方案 0 引言 什么是词云分析? 词云图,也叫文字云,是对文本中出现频率较高的"关键词"予以视 ...

  7. python爬虫(6)——获取天猫商品评论信息

    本文以读取商品评论的json数据的方式来获取天猫商品评论,本文所采用的方法借鉴自知乎某大神(https://www.zhihu.com/question/36524413),可以非常方便地爬取特定商品 ...

  8. 通过爬取天猫商品评论实例分析Python爬取ajax动态生成的数据

    本文主要通过爬取天猫商品kindle的评论为例来说明利用python爬取ajax动态生成的数据的方式,本文使用的工具如下: 工具 chrome浏览器[寻找评论的动态链接] python3.5[执行代码 ...

  9. Python3中级玩家:淘宝天猫商品搜索爬虫自动化工具(第三篇)

    查看Github 欢迎回看第一篇和第二篇. Python3中级玩家:Python3中级玩家:淘宝天猫商品搜索爬虫自动化工具(第一篇 Python3中级玩家:Python3中级玩家:淘宝天猫商品搜索爬虫 ...

最新文章

  1. 云原生如此重要,可惜80%的人都不知道
  2. Html5之基础-7 HTML列表
  3. GRE核心词汇助记与精练-List11弯、折、扭
  4. 23种设计模式C++源码与UML实现--命令模式
  5. 华为正式发布鸿蒙多久可以用,华为正式发布鸿蒙OS,手机随时能用
  6. 以计算机谈人文科学,阅读下面一段文字,完成问题   自20世纪80年代以来,世界都在谈“软科学技术”,何谓软科学?经常听人说:“脑子不够使。”这其实就是对软科学的需求。于是,从古至今,...
  7. win7如何安装mysql5.7_Win7下安装MySQL5.7备忘
  8. Python selenium 滚动页面以及滚动至元素可见(转载)
  9. 大华流媒体服务器连接显示器,如何从海康平台上拉流接入RTSP安防网络摄像头/海康大华硬盘录像机网页无插件直播流媒体服务器EasyNVR?...
  10. 天问:《三体》世界真的存在吗?(太阳系与银河系简介)
  11. 紫砂壶的起源 计算机操作题,紫砂壶的起源与历史发展你知道吗?
  12. ElasticSearch汇总
  13. Java面试题-微服务
  14. Unity学习-熟悉环境
  15. Thymeleaf 变量输出与字符串操作
  16. java 月份缩写_关于java:如何将日期字符串解析为Date?
  17. 手撸 SpringBoot DDD 微服务脚手架
  18. 十大网站布局和颜色搭配评析
  19. 【pyecharts50例】渐变色效果柱状图(直方图)~
  20. Revit二次开发---关于CAD翻模第一步

热门文章

  1. Ensemble Learning(集成学习--AdaBoost,GBDT,Xgboost等)
  2. 【RT-Thread Smart】ART-Pi Smart 开发板开箱及爱之初次体验
  3. 我是如何让公司后台管理系统焕然一新的(上) -性能优化
  4. 万字长文 | 这可能是东半球最保姆级的后台服务器开发学习路线
  5. python开发工程师是干嘛的-python工程师是做什么的
  6. 安卓4.4.4安装哪个微信版本_新版微信被网友骂惨了,后悔更新了吗?教你一招迅速回到旧版本...
  7. 【入门6】函数与结构体【完结】
  8. 六边形俄罗斯方块游戏创意
  9. 区块链 图灵完备是什么
  10. tyvj 火焰巨魔的惆怅