前一段时间爬取了天猫某些商品的评论数据并进行轻度处理,今天就跟大家聊聊见解吧!
话不多说直接开始:
大家都知道淘宝天猫作为国内最大的电商平台之一, 它对网站的加工是极好的,网站的配置也是非常完美的,其中就包括了反爬虫的设计. 淘宝的登录页面是可以检测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()
最后就来看看我们的辛苦结果吧
感觉怎么样, 都还喜欢嘛?有什么问题可以在下面评论哦! 我会在线上解答问题哦! 项目我也放到资源里了, 需要的可以去下载哦!
最后再加一句, 欢迎来评论交流哦!