scrapy爬虫之《琅琊榜2》话题title收集及词云展示

简介

最近看微信公众号上好多文档关于豆瓣上电影的影评分析的,感觉挺有意思的,就拿《琅琊榜2》也来尝试下。本文主要是使用scrapy爬取豆瓣上的《琅琊榜2》的话题讨论区并用作词云展示。至于为什么使用scrapy,主要是之前使用过python的beautifulsoup、selenium等模块,各个功能都是自己写的,不是很系统,而scrapy作为爬虫框架内置css、xpath且异步抓取,效率很高。

实现

一、爬取豆瓣话题title
1.准备python环境
当然还是使用conda,之前博文中提到过很多次,在此不必多说。

mkdir -p /home/yanggd/scrapy
cd /home/yanggd/scrapy
conda create -n scrapy
#切换至scrapy虚拟环境中
source activate scrapy

2.安装scrapy
具体安装可见官方文档”https://docs.scrapy.org/en/latest/intro/install.html

conda install -c conda-forge scrapy

3.创建scrapy项目

scrapy startproject douban

4.创建爬虫

cd douban
scrapy genspider langyabang movie.douban.com

创建后会在douban目录下生成douban子目录,在douban/spiders/下查看生成的初始化爬虫

vim douban/spiders/langyabang.py
# -*- coding: utf-8 -*-
import scrapy
class LangyabangSpider(scrapy.Spider):
    name = 'langyabang'
    allowed_domains = ['movie.douban.com']
    start_urls = ['https://movie.douban.com']

    def parse(self, response):
    pass

5.编写爬虫脚本

vim douban/spiders/langyabang.py
# -*- coding: utf-8 -*-
import scrapy

class LangyabangSpider(scrapy.Spider):
    name = 'langyabang'
    allowed_domains = ['movie.douban.com']
    start_urls = ['https://movie.douban.com/subject/26665065/discussion/']

    def parse(self, response):
        for comment in response.xpath("//a[@title]/text()").extract():
                yield {
                        'title': comment.strip().encode('utf-8')
                }

        #next_page = response.xpath("//div[@class='paginator']/a/@href").extract_first()
        next_page = response.xpath("//div[@class='paginator']/span[@class='next']/a/@href").extract_first()
        if next_page is not None:
                yield response.follow(next_page, callback=self.parse)

说明:
name 是我们爬虫的名字
start_urls 是我们需要爬取的话题讨论区的起始页
response.xpath(“//a[@title]/text()”).extract() 我们提取的是每个话题的title
comment.strip().encode(‘utf-8’) 会对抓取的title内容进行去除空间或换行等操作
response.xpath(“//div[@class=’paginator’]/span[@class=’next’]/a/@href”).extract_first() 我们提取的是下一页的链接,是一个相对url,用于跳转页面
response.follow(next_page, callback=self.parse) 会根据当前的url和下一页的链接进行跳转

6.运行爬虫

scrapy crawl langyabang -o langyabang.json

但我们运行后,打印信息会有以下提示:

2017-12-27 08:30:28 [scrapy.core.engine] INFO: Spider opened
2017-12-27 08:30:28 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2017-12-27 08:30:28 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6024
2017-12-27 08:30:28 [scrapy.core.engine] DEBUG: Crawled (403) <GET https://movie.douban.com/robots.txt> (referer: None)
2017-12-27 08:30:28 [scrapy.core.engine] DEBUG: Crawled (403) <GET https://movie.douban.com/subject/26665065/discussion/> (referer: None)
2017-12-27 08:30:28 [scrapy.spidermiddlewares.httperror] INFO: Ignoring response <403 https://movie.douban.com/subject/26665065/discussion/>: HTTP status code is not handled or not allowed

爬虫返回的状态码为403,看来豆瓣对user_agent进行了相关设置,scpray默认的user_agent为#USER_AGENT = ‘douban (+http://www.yourdomain.com)’,如此看来我们需要将爬虫的useragent改以下,有两种方案:一是改成固定的,二是改成随机的。请参考scrapy随机更改User-Agent方法
我们此次为了方便,改成固定的了,如下:

vim douban/settings.py
USER_AGENT = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)'

再次运行爬虫,我们发现爬虫的内容不是汉字,究其原因由官方文档解释:

FEED_EXPORT_ENCODING

Default: None

The encoding to be used for the feed.

If unset or set to None (default) it uses UTF-8 for everything except JSON output, which uses safe numeric encoding (\uXXXX sequences) for historic reasons.

Use utf-8 if you want UTF-8 for JSON too.

竟然是除了json外,其他格式都用utf-8编码,因此我们需要再次设置:

vim douban/settings.py
FEED_EXPORT_ENCODING='utf-8'

ok,至此我们再运行爬虫,发现可以正常爬取了。

scrapy crawl langyabang -o langyabang.json
vim langyabang.json
[
{"title": "反派好强大啊,希望编剧能驾驭住"},
{"title": "15集 精妙的布局与破局"},
{"title": "为什么不用原音?好像所有演员都是配音"},
{"title": "看到六集,关于本剧的年轻演员"},
{"title": "林奚怎么发现妆盒的问题的"},
{"title": "原来教主第二十七集领盒饭"},
{"title": "有人萌老皇帝吗"},
{"title": "孔导的访谈!!信息量挺大!都进来看看!!萧平章..."},
{"title": "打完一星之後就滾蛋好嗎?都棄劇了還嗶嗶嗶…"},
{"title": "[第15集] 15集最后元启烧信"},
{"title": "看到第二集就不想看了。。。"},
{"title": "难道充vip看剧有罪吗,冲vip就得去死么???"},
{"title": "在这儿推荐下隔壁《端脑》。。良心漫改剧"},
{"title": "庭生的真实身份会不会被挖出来?"},
{"title": "林怼怼?与寒潭小神龙?小神龙的日常"},
{"title": "平章估计是誉王的后人....元启的升级太突然太生硬。"},
{"title": "变宫斗剧了?"},
{"title": "荀大统领的萌点"},
{"title": "萧元启的父亲究竟是怎么死的"},
{"title": "萧平章八成是誉王遗腹子的儿子!"},
{"title": "[第16集] 平旌像被调戏的小媳妇似的委屈脸迅速拉上..."},
{"title": "有人說8.3分是水軍刷出來的…"},
{"title": "已被卡粉梅长苏圈粉"},
{"title": "这个分数我感觉是刷的"},
{"title": "真的别把差评都推在胡椒头上了"},
{"title": "这剧太烂了,看不下去"},
{"title": "胡歌和《琅琊榜》是互相成就的,所以别互黑了。。"},
{"title": "含着一只苍蝇吃一桌好菜"},
{"title": "萧平旌的武力值到底有多高啊?"},
......
......

至此我们的爬虫已经完成了工作,下一步我们是根据爬取的内容生成词云。

二、生产词云
我们根据我以前的博文python生成词云,因此我们需要提前准备关键词文本、中文字体及一张图片。
1.准备
关键词来源于我们爬取的title,但我们使用的是json格式,因此需要换成csv格式

scrapy crawl langyabang -o langyabang.csv

中文字体我们使用simsun.ttc

图片我们在网上随便找了一张
因此,我们词云的准备如下:

.
└── wordcloud
    ├── langyabang.csv
    ├── langyabang.jpg
    ├── langyabang_new.jpg
    ├── langyabang.py
    └── simsun.ttc

其中langyabang_new.jpg是基于langyabang.jpg生成的词云图片
2.编写脚本

vim langyabang.py
#!/home/yanggd/miniconda2/envs/wordcloud/bin/python
#-*- coding: utf-8 -*-

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

#读取脚本所在目录
mulu = path.dirname(__file__)

#从文本中生成关键词
csv = open(path.join(mulu, 'langyabang.csv')).read()
seg_list = jieba.cut(csv, cut_all=True)
seg_split = " ".join(seg_list)

#读取图片
wordcloud_mask = np.array(Image.open(path.join(mulu, "langyabang.jpg")))

#字体位置
font = path.join(mulu, 'simsun.ttc')

#设置图片属性
wc = WordCloud(font_path=font, background_color="white", max_words=1000, mask=wordcloud_mask, max_font_size=50)
wc.generate(seg_split)

#生成新的图片
wc.to_file(path.join(mulu, "langyabang_new.jpg"))

#图片展示
plt.imshow(wc, interpolation='bilinear')
plt.axis("off")
plt.show()

3.运行脚本

python langyabang.py

生成图片:
琅琊榜2词云

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值