66.10-scrapy-redis组件使用和 花木兰2020 豆瓣影评爬取

以前总认为坚持会让我们变强大,但是长大后才发现,让我们强大的,是放下!


总结:

  1. span里面 直接是文本用 /text(); 或者// text();
    response.xpath("//div[@class="comment-item"]//span[@class="short"]/text()")
    response.xpath("//div[@class="comment-item"]//span[@class="short"]//text()")

1. Scrapy-redis组件

这是一个能给Scrapy框架引入分布式的组件。


分布式由Redis提供,可以在不同节点上运行爬虫,共用同一个Redis实例。在Redis中存储待爬取的URLs、Items。

1.1 安装
$ pip install scrapy-redis

安装要求
Python 2.7, 3.4 or 3.5 Redis >= 2.8
Scrapy >= 1.0 redis-py >= 2.10

#---------------------------------------------
Installing collected packages: scrapy-redis, zope.interface
Successfully installed scrapy-redis-0.6.8 zope.interface-5.1.0
1.2 配置
# Enables scheduling storing requests queue in redis. 
SCHEDULER = "scrapy_redis.scheduler.Scheduler"

# Ensure all spiders share same duplicates filter through redis. 
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

# Store scraped item in redis for post-processing.
ITEM_PIPELINES = { 'scrapy_redis.pipelines.RedisPipeline': 300}

# The item pipeline serializes and stores the items in this redis key.
# 这个key很重要
#REDIS_ITEMS_KEY = '%(spider)s:items'

# Specify the host and port to use when connecting to Redis (optional). 
#REDIS_HOST = 'localhost'
#REDIS_PORT = 6379

# Default start urls key for RedisSpider and RedisCrawlSpider.
#REDIS_START_URLS_KEY = '%(name)s:start_urls'

在以下方面做了增强

Scheduler + Duplication Filter, Item Pipeline, Base Spiders

Scheduler
本质上将原来的普通队列,变成了redis以提供多爬虫多进程共享,并行能力增强。

Duplication Filter
scrapy使用set来去重,scrapy-redis使用redis的set类型去重 Item Pipeline

Item Pipelline
在Item Pipeline增加一个处理,即将数据items存入redis的items queue中 Base Spiders

Base Spiders
提供了使用了RedisMixin的RedisSpider和RedisCrawlSpider,从Redis中读取Url。

Redis是服务,爬虫就是它的客户端,客户端就可以扩展出并行的很多爬虫一起爬取。

2. redis安装

这里不再赘述。

3. 豆瓣影评分析项目

(F:\Pyenv\conda3.8) F:\Projects\spider>scrapy startproject dbreview .

(F:\Pyenv\conda3.8) F:\Projects\spider>scrapy genspider -t crawl review douban.com

Created spider 'review' using template 'crawl' in module:
  dbreview.spiders.review
3.1 抓取内容分析

抓取最新top 1电影,分析其影评
提取影评的xpath = //div[@class="comment-item"]//span[@class="short"]

3.2 创建Scrapy项目

$ scrapy startproject review .

3.3 配置
# settings
BOT_NAME = 'dbreview'

SPIDER_MODULES = ['dbreview.spiders']
NEWSPIDER_MODULE = 'dbreview.spiders'

USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36"

ROBOTSTXT_OBEY = False
CONCURRENT_REQUESTS = 4
DOWNLOAD_DELAY = 1
COOKIES_ENABLED = False   # 每一次全新的请求;

# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False


# Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
#    'dbreview.middlewares.DbreviewSpiderMiddleware': 543,
#}

# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
#    'dbreview.middlewares.DbreviewDownloaderMiddleware': 543,
#}

# Enable or disable extensions
# See https://docs.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
#    'scrapy.extensions.telnet.TelnetConsole': None,
#}

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
# ITEM_PIPELINES = {
# #    'dbreview.pipelines.DbreviewPipeline': 299,
# 'scrapy_redis.pipelines.RedisPipeline': 300
# }



SCHEDULER = "scrapy_redis.scheduler.Scheduler"

DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

REDIS_HOST = '192.168.0.100'
REDIS_PORT = 6379

3.4 构建Item
import scrapy

class ReviewItem(scrapy.Item): 
    review = scrapy.Field()

# spider
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from ..items import DbreviewItem

class ReviewSpider(CrawlSpider):
    name = 'review'
    allowed_domains = ['douban.com']
    start_urls = ['https://movie.douban.com/subject/26357307/comments']

    rules = (
        Rule(LinkExtractor(allow=r'start=\d+'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):

        item = DbreviewItem()
        item['comment'] = response.xpath('//div[@class="comment-item"]//span[@class="short"]/text()').extract_first()
        print(dict(item), '+++++++++++++')
        yield item
3.5 构建爬虫scrapy-redis

写完先测试,然后将类型改为RedisCrawlSpider

$ scrapy genspider -t crawl dbreview douban.com

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from ..items import DbreviewItem
from scrapy_redis.spiders import RedisCrawlSpider
class ReviewSpider(RedisCrawlSpider):
    name = 'review'
    allowed_domains = ['douban.com']
    start_urls = ['https://movie.douban.com/subject/26357307/comments']

    rules = (
        Rule(LinkExtractor(allow=r'start=\d+'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):

        item = DbreviewItem()
        item['comment'] = response.xpath('//div[@class="comment-item"]//span[@class="short"]/text()').extract_first()
        print(dict(item), '+++++++++++++')
        yield item
爬取
$ scrapy crawl dbreview

会发现程序会卡住,这是因为在等待起始URL,手动添加开始url
127.0.0.1:6379> lpush myspider:start_urls https://movie.douban.com/subject/26357307/comments
3.6 分析

使用爬虫,爬取所有数据,然后使用redis中的数据开始分析

import redis
import simplejson

db = redis.Redis('192.168.0.100')
print(db.keys('*'))
reviewlist = db.lrange('review:items', 0, -1)

for comment in reviewlist:
    try:
        review = simplejson.loads(comment).get('comment')
        print(review)
        print('-----------------------')
    except Exception as e:
        print(e)
#--------------------------------------------------------
迪士尼撸出来的玩意,糟蹋了一个好题材,一帮中国演员说着不那么标准的英语在那里拿腔拿调的念台词真是尴尬至极
-----------------------
(70/100)工整流畅合格的商业片。迪士尼公主电影里品质上乘的存在。刘亦菲的表演是没有问题的,动作戏精彩,画面质感一流,片尾出字幕时的title design超好看。中国公主花木兰没有让人失望。
-----------------------
太出戏了,河北土楼?Niubi
-----------------------
跟玩似的,弱智一群人,成就一个人。
真实与逻辑并不需要。
-----------------------
先说结论:壳是中国壳,魂还是老外那个劲,造型是日本艺伎,内核是老美超级英雄主义。
总之是外国对中国片面化的认识。
。。。。。。
看完挺不适的,电影还是明显的迪士尼风格。能理解迪士尼想凸现花木兰的英勇女性角色,但是如果这种精神是以贬低中国和女性为衬托,那么我表示拒绝!整体挺局限的,从巩俐女巫角色的莫名其妙到刚训练不久的几人小队拯救国家和皇帝,再到整体营造的女性以三从四德和嫁人为荣耀的奇怪思想。多种文化杂糅,多重风格杂糅。影片显然不了解中国文化和花木兰精神。大概从头至尾最能提现花木兰精神的就是剑上那几个字了吧。
-----------------------


1. jieba分词——结巴分词

安装 pip install jieba
官网 https://github.com/fxsjy/jieba
测试代码

import jieba

seg_list = jieba.cut("我来到北京清华大学", cut_all=True)
print("Full Mode: " + "/ ".join(seg_list))  # 全模式

seg_list = jieba.cut("我来到北京清华大学", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list))  # 精确模式

seg_list = jieba.lcut("他来到了网易杭研大厦")  # 默认是精确模式
print(seg_list)

seg_list = jieba.lcut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造")  # 搜索引擎模式
print(seg_list)
# ------------------------------------------------
Full Mode: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学
Default Mode: 我/ 来到/ 北京/ 清华大学
['他', '来到', '了', '网易', '杭研', '大厦']
['小明', '硕士', '毕业', '于', '中国', '科学', '学院', '科学院', '中国科学院', '计算', '计算所', ',', '后', '在', '日本', '京都', '大学', '日本京都大学', '深造']
2. stopword 停用词

数据清洗:把脏数据洗掉。检测出并去除掉数据中无效或无关的数据。例如,空值、非法值的检测,重复数据检测等。

对于一条条影评来说,我们分析的数据中包含了很多无效的数据,比如标点符号、英文的冠词、中文"的"等等,需要把它们清除掉。

使用停用词来去除这些无效的数据。

wordcloud词云 https://amueller.github.io/word_cloud/index.html

依赖numpy、matplotlib
pip install wordcloud

matplotlib:python中绘制二维图的模块。
pip install matplotlib



常用方法

WordCloud参数

font_path:指明要用的字体的路径
width:默认值400。设定词云画布的宽度
height:默认值200。画布高度
mask:默认无。用来设定词云的形状
min_font_size:默认值4,整数类型。设定最小的词的尺寸/大小
max_font_size:默认无,整数型。设定最大词的大小
max_words:默认值200。设定词云最多显示的词的个数
background_color:默认值为黑色。设定词云画布底色
Scale:默认值1。值越大,图像密度越大越清晰

import redis
import simplejson, jieba
form wordcloud import WordCloud
import matplotlib.pyplot as plt

# 使用停用词
stopwords = set()
with open('./chineseStopWords.txt', encoding='gbk') as f:
    for line in f:
        stopwords.add(line.rstrip('\r\r'))
    stopwords.add(' ')


# 分析
db = redis.Redis('192.168.0.100')
print(db.keys('*'))
reviewlist = db.lrange('review:items', 0, -1)

words = {}
total = 0

for comment in reviewlist:
    try:
        review = simplejson.loads(comment).get('comment')
        print(review)
        for word in jieba.cut(review):
            if word in stopwords:
                words[word] = words.get(word, 0) + 1
                total += 1
        print('-----------------------')
    except Exception as e:
        print(e)

print(words)
print(sorted(words.items(), key=lambda x: x[1], reverse=True))


# 词云
frenq = {word:count/total for word, count in words.items()}

# 用什么字体、背景色、最大字体
wordcloud = WordCloud(font_path='simhei.ttf', max_font_size=40, scale=15)
wordcloud.fit_words(frenq)  # 使用单词和词频创建词

plt.figure(2)
plt.imshow(wordcloud, interpolation="bilinear")  # 将一个图显示在二维坐标
plt.axis("off")    # 不打印坐标系
plt.show()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,230评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,261评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,089评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,542评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,542评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,544评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,922评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,578评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,816评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,576评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,658评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,359评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,920评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,859评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,381评论 2 342