专栏首页数据STUDIO手把手教你用Python爬取某网小说数据,并进行可视化分析

手把手教你用Python爬取某网小说数据,并进行可视化分析

大家好,我是云朵君!

本号「数据STUDIO」长期接受有偿投稿,公号菜单栏【云朵之家】-【投稿】可查看征稿文档!

👆点击关注|设为星标|干货速递👆


网络文学是以互联网为展示平台和传播媒介,借助相关互联网手段来表现文学作品及含有一部分文字作品的网络技术产品,在当前成为一种新兴的文学现象,并快速兴起,各种网络小说也是层出不穷,今天我们使用selenium爬取红袖天香网站小说数据,并做简单数据可视化分析。

红袖添香建于1999年,是全球领先的女性文学数字版权运营商之一,日更新小说5000部,为超过240万注册用户提供涵盖小说、散文、杂文、诗歌、歌词、剧本、日记等体裁的高品质创作和阅读服务,在言情、职场小说等女性文学写作及出版领域独占高地。(百度百科)

网页初步分析

打开网页如图所示:

我们要把小说分类里面的所有小说数据全部抓取下来:总共有50个页面,每页20条数据,一共1000条数据。

首先使用requests第三方库请求数据,如下所示:

import requests
url = 'https://www.hongxiu.com/category/f1_f1_f1_f1_f1_f1_0_1' # 第一页url
headers = { 'xxx' : 'xxx'}
res = requests.get(url,headers=headers)
print(data.content.decode('utf-8'))

我们发现请求回来的数据并没有第一页的小说数据信息,很明显数据不在网页源码里面,然后通过查看network,发现了这样的请求字段:

_csrfToken: btXPBUerIB1DABWiVC7TspEYvekXtzMghhCMdN43
_: 1630664902028

这个是做了js加密,所以为了避免分析加密方式,使用selenium爬取数据可能更快一些。

selenium 爬取数据

01 初步测试

from selenium import webdriver
import time

url = 'https://y.qq.com/n/ryqq/songDetail/0006wgUu1hHP0N'

driver = webdriver.Chrome()

driver.get(url)

结果运行正常,没有问题。

02 小说数据

明确要爬取的小说数据信息

图片链接、名称、作者、类型、是否完结、人气、简介

然后通过点击下一页的按钮观察是否是动态数据:发现不是;url规律如下所示:

'https://www.hongxiu.com/category/f1_f1_f1_f1_f1_f1_0_1' # 第一页的url
'https://www.hongxiu.com/category/f1_f1_f1_f1_f1_f1_0_2' # 第二页的url

03 解析数据

下面是解析页面数据的代码:

def get_data():
    ficList = [] # 存储每一页的数据
    items = driver.find_elements_by_xpath("//div[@class="right-book-list"]/ul/li")
    for item in items:
        dic = {}
        imgLink = item.find_element_by_xpath("./div[1]/a/img").get_attribute('src') 
        # 1.图片链接 2.小说名称(name)  3.小说类型(types) ....
        dic['img'] = imgLink
        # ...... 
        ficList.append(dic)

这里有几个需要注意的点:

  1. 注意xpath语句书写,注意细节,不要出错;
  2. 对于小说简介,有的简介比较长,有换行符,为了便于存储,需要使用字符串的replace方法把'\n'替换为空字符串

04 翻页爬取

下面是翻页爬取数据的代码:

try:
    time.sleep(3)
    js = "window.scrollTo(0,100000)"
    driver.execute_script(js)
    while driver.find_element_by_xpath( "//div[@class='lbf-pagination']/ul/li[last()]/a"):
        driver.find_element_by_xpath("//div[@class='lbf-pagination']/ul/li[last()]/a").click()
        time.sleep(3)
        getFiction()
        print(count, "*" * 20)
        count += 1
        if count >= 50:
            return None

except Exception as e:
    print(e)

代码说明:

使用try语句,进行异常处理,防止有什么特殊页面的元素无法匹配或者其它问题。

driver执行js代码,操作滚轮,滑动到页面底部。

js = "window.scrollTo(0,100000)"
driver.execute_script(js)

time.sleep(n) 因为循环里面添加了解析函数(driver定位)需要等待数据加载完全。

while循环语句,while后面的是 ‘下一页’ 按钮定位,保证循环的爬取下一页的数据。

使用if语句作为判断条件,作为while循环推出的条件,然后要使用return退出函数,break不行。

05 数据保存

titles = ['imgLink', 'name', 'author', 'types', 'pink','popu','intro']
with open('hx.csv',mode='w',encoding='utf-8',newline='') as f:
    writer = csv.DictWriter(f, titles)
    writer.writeheader()
    writer.writerows(data)
    print('写入成功')

06 程序运行

结果如下,显示的1000条数据:

使用selenium爬取数据的一些注意点:

① 点击下一页之后,数据不可能瞬间加载完全,一旦数据没有加载完全,那么使用webdriver的find_Element_by_xpath语句就会定位不到dom文档上的元素,进而抛出一个错误:

selenium.StaleElementReferenceException:   
stale element reference: element is not   
attached to the page document

大概意思:所引用的元素已过时,不再依附于当前页面。 产生原因:通常情况下,这是因为页面进行了刷新或跳转。 解决方法: 1.重新使用 findElement 或 findElements 方法进行元素定位即可。 2.或者只需要使用webdriver.Chrome().refresh刷新一下网页就可以,还要在前面等待几秒钟再刷新,time.sleep(5)。 关于这个报错的解决方法,参考下面博客: https://www.cnblogs.com/qiu-hua/p/12603675.html

② 在动态点击下一页按钮时,需要精准定位到下一页的按钮,其次很重要的一共问题,selenium打开浏览器页面时,需要窗口最大化

由于窗口右侧有一个绝对定位的二维码小窗口,如果不窗口最大化,那个该窗口就会挡住下一页按钮导致无法点击,这个需要注意。

数据分析与可视化

打开文件

import pandas as pd
data = pd.read_csv('./hx.csv')
data.head()

根据我们的数据信息可以做如下的可视化展示:

01 不同类型小说占比

types = ['现代言情', '古代言情', '玄幻', '玄幻言情', '科幻空间', '仙侠', '都市', '历史', '科幻', '仙侠奇缘', '浪漫青春', '其它']
number = [343, 285,  83,  56,  45,  41,  41,  25,  14,  14,  13,40]

pyecharts饼图

from pyecharts import options as opts
from pyecharts.charts import Page, Pie
pie=(
    Pie()
    .add(
            "",
            [list(z) for z in zip(types, number)],
            radius=["40%", "75%"],
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="不同类型小说占比"),
            legend_opts=opts.LegendOpts(
                orient="vertical", pos_top="15%", pos_left="2%"
            ),
        )
        .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
    )

pie.render('pie.html')

结果如图

由图可知,言情小说占据所有小说半壁江山。

02 完结小说占比

from pyecharts import options as opts
from pyecharts.charts import Page, Pie

ty = ['已完结','连载中']
num = [723,269]
pie=(
        Pie()
        .add("", [list(z) for z in zip(ty,num)])
        .set_global_opts(title_opts=opts.TitleOpts(title="完结小说占比"))
        .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
        )

pie.render('pie1.html')

结果如图:

由图可知,仍有超1/4的小说正在连载中。

03 小说简介词云图展示

生成.txt文件

with open('hx.txt','a',encoding='utf-8') as f:
    for s in data['intro']:
        f.write(s + '\n')

初始化设置

# 导入相应的库
import jieba
from PIL import Image
import numpy as np
from wordcloud import WordCloud
import matplotlib.pyplot as plt
# 导入文本数据并进行简单的文本处理
# 去掉换行符和空格
text = open("./hx.txt",encoding='utf-8').read()
text = text.replace('\n',"").replace("\u3000","")

# 分词,返回结果为词的列表
text_cut = jieba.lcut(text)
# 将分好的词用某个符号分割开连成字符串
text_cut = ' '.join(text_cut)

词云展示

word_list = jieba.cut(text)
space_word_list = ' '.join(word_list)
# print(space_word_list) 打印文字  可以省略
# 调用包PIL中的open方法,读取图片文件,通过numpy中的array方法生成数组
mask_pic = np.array(Image.open("./xin.png"))
word = WordCloud(
    font_path='C:/Windows/Fonts/simfang.ttf',  # 设置字体,本机的字体
    mask=mask_pic,  # 设置背景图片
    background_color='white',  # 设置背景颜色
    max_font_size=150,  # 设置字体最大值
    max_words=2000,  # 设置最大显示字数
    stopwords={'的'}  # 设置停用词,停用词则不在词云途中表示
                 ).generate(space_word_list)
image = word.to_image()
word.to_file('h.png')  # 保存图片
image.show()

结果如图

这里不能从图中看出特别的内容,我们可以考虑其他的一些更加有效的自然语言分析与处理方法,此处留给读者朋友们一起思考。

04 根据类型分析小说热度排行

from pyecharts.charts import Bar
from pyecharts import options as opts
bar = Bar()
bar.add_xaxis(list(c['types'].values))
bar.add_yaxis('小说热度排行',numList)
bar.set_global_opts(xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)))
bar.render()

结果如图

可以看出来,言情小说从古至今都是永恒的话题...

言情小说是中国旧体小说的一种,又称才子佳人小说。以讲述异性相爱为中心,通过完整的故事情节和具体的环境描写来反映爱情的心理、状态、事物等社会生活的一种文学体裁。 言情小说类型很多主要分为古代,现代等题材。其中又有重生文、穿越文、反穿越文、科幻文、宅斗文、宫斗文、玄幻文、公路文等不同题材。(百度百科)

05 不同作者热点小说占比

我们通过查看作家写的小说数量,得到以下结果:

data['author'].value_counts()

根据写作数量最多的前三位作家,他们只写了言情小说,后两位写了多种小说。接下来分别分析这些小说家中言情小说家及其他小说家的热度。

言情小说家热度

from pyecharts import options as opts
from pyecharts.charts import Page, Pie
attr = ["希行", "吱吱", "青铜穗"]
v1 = [1383,1315,1074]

pie=(
        Pie()
        .add("", [list(z) for z in zip(attr,v1)])
        .set_global_opts(title_opts=opts.TitleOpts(title="言情小说作家热度"))
        .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
        )

pie.render('pie.html')

这三个小说家热度伯仲之间,当然,热度最高的当属希行

希行,为笔名,原名裴云, 女, 起点中文网古言代表作家之一,女性网络文学超人气作者。中国作家协会会员。橙瓜见证·网络文学20年百强大神作家。2009年创作至今,希行已完结作品已有11部,创作1000多万字,作品大多简繁出版,其中《娇娘医经》、《君九龄》已出售影视权。(百度百科)

两大小说家热度排行

from pyecharts.charts import Bar
from pyecharts import options as opts

bar = Bar()
#指定柱状图的横坐标
bar.add_xaxis(['玄幻','奇幻','仙侠'])
#指定柱状图的纵坐标,而且可以指定多个纵坐标
bar.add_yaxis("唐家三少", [2315,279,192])
bar.add_yaxis("我吃西红柿", [552,814,900])
#指定柱状图的标题
bar.set_global_opts(title_opts=opts.TitleOpts(title="热度小说排行"))
#参数指定生成的html名称
bar.render('tw.html')

如图所示,唐家三少的玄幻小说更加突出,而 我吃西红柿 三种小说热度更加平均。

写在最后

这个爬取红袖添香网站小说页面数据,我们使用到selenium进行数据抓取,由于页面的js加密,所以使用到selenium,然后对于注意点进行总结:

① selenium爬取数据需要注意几点:

  • 各种元素的定位需要精确;
  • 由于使用selenium需要加载js代码,元素需要全部加载完全,才能进行定位,所以打开网页需要设置time.sleep(n);
  • 然后对于很多网站都有个绝对定位的元素,可能是二维码...,固定在电脑屏幕的位置,不会随着页面滚轮的滚动而移动,所以需要页面最大化,防止该窗口挡住页面元素,导致无法点击或者其它操作。

② 在数据可视化展示的时候要进行数据清洗,因为有的数据是不规范的,比如会出现这样的错误:

'utf-8' codec can't decode byte 0xcb in 
position 2: invalid continuation byte

这是由于编码方式的不同导致,一般通过查看页面meta标签的charset属性得到编码方式,设置pandas打开文件时的encoding的属性值;如果还是报错,可以把属性值修改成 'gb18030'

<meta charset="UTF-8">

备注,本文仅以学习交流,对于爬虫浅尝辄止,以免对服务器增加负担。

OK,今天的分享就到这里啦!

本文分享自微信公众号 - 数据STUDIO(jim_learning),作者:游世九黎

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-09-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 手把手教你用Matplotlib进行数据可视化

    导读:Matplotlib是建立在NumPy数组上的一个多平台数据可视化库。在2002年,约翰·亨特(John Hunter)提出Matplotlib,最初的构...

    华章科技
  • 手把手教你用Bokeh进行可视化数据分析(附源码)

    上一篇利用交互式可视化分析了一下金州勇士队4年3冠的原因,其中数据处理部分使用了numpy和pandas,可视化部分使用的是Bokeh和Plotly,效果非常赞...

    Python数据科学
  • 手把手教你使用Python进行高级数据可视化

    数据可视化能力已经越来越成为各岗位的基础技能。领英的数据报告显示,数据可视化技能在2018年中国最热门技能中排名第一。

    CDA数据分析师
  • 手把手教你用Python进行城市公交网络分析与可视化

    总的数据有 30396 条,站名称缺失了 5 条,纬度(分)缺失了 1 条,经度(分)缺失了 38 条,为了处理方便,直接把有缺失值的行删除。

    Python进阶者
  • 手把手教你调试代码并使用Echarts进行数据可视化

    大家好,在昨天的文章中我们详细讲解了如何使用requests+bs4爬取美国疫情实时数据,但是在文章发布之后大约三个小时就有读者后台留言说怎么代码不能用了,在第...

    刘早起
  • 手把手教你利用Pyecharts库对IP代理数据进行数据可视化分析

    前几天小编发布了手把手教你使用Python爬取西次代理数据(上篇)和手把手教你使用Python爬取西次代理数据(下篇),木有赶上车的小伙伴,可以戳进去看看。今天...

    Python进阶者
  • Python数据分析:手把手教你用Pandas生成可视化图表

    我的机器学习教程「美团」算法工程师带你入门机器学习   已经开始更新了,欢迎大家订阅~

    用户7886150
  • 手把手教你用Python网络爬虫获取B站UP主10万条数据并用Pandas库进行趣味数据分析

    大家好,我是Python进阶者!今天来给大家分享小小明的另一篇巨作,上一次分享了他开发的一个filetools,十分好用,这篇文章里边也会用到,没来得及...

    Python进阶者
  • 一键查询明星个人信息,并以知识图谱可视化展示

    最近想搞一点好玩的事情(技术),今天打算做一个小程序:一键查询明星个人信息。(从数据抓取到知识图谱展示,全程代码完成原创,不涉及调用api包)

    Python研究者
  • 推荐一个自学Python的好地方!

    今天给大家分享几个我收藏的宝藏公众号资源。涵盖了Python基础、爬虫、数据分析、数据可视化、算法与人工智能等优质资源,关注之后肯定会大有收货~

    小F
  • 手把手教你用Pyecharts库对淘宝数据进行可视化展示

    大家好,我是Python进阶者。上一篇文章给大家讲到了淘宝数据的预处理和词频处理,没有来得及看的小伙伴,记得去学习了下了,详情戳这里:手把手教你用Pandas...

    Python进阶者
  • 手把手教你用Pyecharts库对淘宝数据进行可视化展示

    大家好,我是Python进阶者,上个礼拜的时候,我的Python交流群里有个名叫程序的大佬,头像是绿色菜狗的那位,在Python交流群里边的人应该都知道我说的是...

    Python进阶者
  • 『爬虫四步走』手把手教你使用Python抓取并存储网页数据!

    爬虫是Python的一个重要的应用,使用Python爬虫我们可以轻松的从互联网中抓取我们想要的数据,本文将基于爬取B站视频热搜榜单数据并存储为例,详细介绍Pyt...

    刘早起
  • 实战|手把手教你用Python爬取存储数据,还能自动在Excel中可视化!

    大家好,在之前我们讲过如何用Python构建一个带有GUI的爬虫小程序,很多本文将迎合热点,延续上次的NBA爬虫GUI,探讨如何爬取虎扑NBA官网数据。 并且将...

    星星在线
  • 百亿身家中年男子告别房地产转行学Python,我们推荐他读这6本书

    导读:几天前,数据叔在界面新闻看到这样一个标题:《【深度】潘石屹张欣彻底告别房地产》。数据叔当时还纳闷,潘老板告别房地产之后要去做什么呢?如今终于有了答案:

    华章科技
  • 【赠书】pandas创始人手把手教你利用Python进行数据分析

    周末就要到了,本次给大家赠送5本Python技术书籍,这次赠送的书籍是《利用Python进行数据分析》。

    用户1508658
  • 手把手教你使用Python获取B站视频并在本地实现弹幕播放功能

    前几天在看B站上的爬虫视频,虽说是免费的,但是要时刻联网,而且快进和后退还需要等待响应,想到这里,小编就觉得有点麻烦,于是乎就想着给它下载下来,这里整理...

    Python进阶者
  • python爬虫入门方法论

    编者注:这是笔者基于自身在入门python爬虫一些感悟,而写作的——入门小参考或建议。本文没有过多讲述学习爬虫需要哪些库或代码,而是期望为初学者提供一些爬虫思维...

    conanma
  • 一个 Pythoner的 Awesome List

    ? 从大三接触 Python 到现在几乎已经有两年的接触经验了,除去中间有一年左右接私活写写 Android 和 Lamp 之外,有 Python 实际项目开...

    CDA数据分析师

扫码关注云+社区

领取腾讯云代金券