摘要: 很多时候,一篇文章可否获得普遍的传播,除了文章自己实打实的质量之外,一个好的标题也相当重要。本文爬取了虎嗅网建站至今共 5 万条新闻标题内容,助你找到起文章标题的技巧与灵感。同时,分享一些值得关注的文章和做者。html
在众多新媒体网站中,「虎嗅」网的文章内容和质量还算不错。在「新榜」科技类公众号排名中,它位居榜单第 3 名,仍是比较受欢迎的。因此选择爬取该网站的文章信息,顺便从中了解一下这几年科技互联网都出现了哪些热点信息。python
「关于虎嗅」git
虎嗅网创办于 2012 年 5 月,是一个聚合优质创新信息与人群的新媒体平台。该平台专一于贡献原创、深度、犀利优质的商业资讯,围绕创新创业的观点进行剖析与交流。虎嗅网的核心,是关注互联网及传统产业的融合、明星公司的起落轨迹、产业潮汐的动力与趋势。github
使用 pyspider 抓取了虎嗅网的主页文章,文章抓取时期为 2012 年建站至 2018 年 11 月 1 日,共计约 5 万篇文章。抓取 了 7 个字段信息:文章标题、做者、发文时间、评论数、收藏数、摘要和文章连接。web
这是要爬取的 网页界面,能够看到是经过 AJAX 加载的。数据库
右键打开开发者工具查看翻页规律,能够看到 URL 请求是 POST 类型,下拉到底部查看 Form Data,表单需提交参数只有 3 项。经尝试, 只提交 page 参数就能成功获取页面的信息,其余两项参数可有可无,因此构造分页爬取很是简单。json
huxiu_hash_code: 39bcd9c3fe9bc69a6b682343ee3f024a
page: 4
last_dateline: 1541123160
复制代码
接着,切换选项卡到 Preview 和 Response 查看网页内容,能够看到数据都位于 data 字段里。total_page 为 2004,表示一共有 2004 页的文章内容,每一页有 25 篇文章,总共约 5 万篇,也就是咱们要爬取的数量。api
以上,咱们就找到了所需内容,接下来能够开始构造爬虫,整个爬取思路比较简单。以前咱们也练习过这一类 Ajax 文章的爬取,能够参考:浏览器
和以前文章不一样的是,这里咱们使用一种新的工具来进行爬取,叫作:pyspider 框架。由国人 binux 大神开发,GitHub Star 数超过 12 K,足以证实它的知名度。能够说,学习爬虫不能不会使用这个框架。
网上关于这个框架的介绍和实操案例很是多,这里仅简单介绍一下。
咱们以前的爬虫都是在 Sublime 、PyCharm 这种 IDE 窗口中执行的,整个爬取过程能够说是处在黑箱中,内部运行的些细节并不太清楚。而 pyspider 一大亮点就在于提供了一个可视化的 WebUI 界面,可以清楚地查看爬虫的运行状况。
pyspider 的架构主要分为 Scheduler(调度器)、Fetcher(抓取器)、Processer(处理器)三个部分。Monitor(监控器)对整个爬取过程进行监控,Result Worker(结果处理器)处理最后抓取的结果。
咱们看看该框架的运行流程大体是怎么样的:
该框架比较容易上手,网页右边是代码区,先定义类(Class)而后在里面添加爬虫的各类方法(也能够称为函数),运行的过程会在左上方显示,左下方则是输出结果的区域。
这里,分享几个不错的教程以供参考:
GitHub 项目地址:github.com/binux/pyspi…
官方主页:docs.pyspider.org/en/latest/
pyspider 中文网:www.pyspider.cn/page/1.html
pyspider 爬虫原理剖析:python.jobbole.com/81109/
pyspider 爬淘宝图案例实操:cuiqingcai.com/2652.html
安装好该框架后,下面咱们能够就开始爬取了。
CMD 命令窗口执行:pyspider all 命令,而后浏览器输入:http://localhost:5000/ 就能够启动 pyspider 。
点击 Create 新建一个项目,Project Name 命名为:huxiu,由于要爬取的 URL 是 POST 类型,因此这里能够先不填写,以后能够在代码中添加,再次点击 Creat 便完成了该项目的新建。
新项目创建好后会自动生成一部分模板代码,咱们只需在此基础上进行修改和完善,而后就能够运行爬虫项目了。如今,简单梳理下代码编写步骤。
from pyspider.libs.base_handler import *
class Handler(BaseHandler):
crawl_config:{
"headers":{
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'
}
}
def on_start(self):
for page in range(2,3): # 先循环1页
print('正在爬取第 %s 页' % page)
self.crawl('https://www.huxiu.com/v2_action/article_list',method='POST',data={'page':page}, callback=self.index_page)
复制代码
这里,首先定义了一个 Handler 主类,整个爬虫项目都主要在该类下完成。 接着,能够将爬虫基本的一些基本配置,好比 Headers、代理等设置写在下面的 crawl_config 属性中。(若是你尚未习惯从函数(def)转换到类(Class)的代码写法,那么须要先了解一下类的相关知识,以后我也会单独用一篇文章介绍一下。)
下面的 on_start() 方法是程序的入口,也就是说程序启动后会首先从这里开始运行。首先,咱们将要爬取的 URL传入 crawl() 方法,同时将 URL 修改为虎嗅网的:www.huxiu.com/v2_action/a… 因为 URL 是 POST 请求,因此咱们还须要增长两个参数:method 和 data。method 表示 HTTP 请求方式,默认是 GET,这里咱们须要设置为 POST;data 是 POST 请求表单参数,只须要添加一个 page 参数便可。
接着,经过 callback 参数定义一个 index_page() 方法,用来解析 crawl() 方法爬取 URL 成功后返回的 Response 响应。在后面的 index_page() 方法中,可使用 PyQuery 提取响应中的所需内容。具体提取方法以下:
import json
from pyquery import PyQuery as pq
def index_page(self, response):
content = response.json['data']
# 注意,在sublime中,json后面须要添加(),pyspider 中则不用
doc = pq(content)
lis = doc('.mod-art').items()
data = [{
'title': item('.msubstr-row2').text(),
'url':'https://www.huxiu.com'+ str(item('.msubstr-row2').attr('href')),
'name': item('.author-name').text(),
'write_time':item('.time').text(),
'comment':item('.icon-cmt+ em').text(),
'favorites':item('.icon-fvr+ em').text(),
'abstract':item('.mob-sub').text()
} for item in lis ] # 列表生成式结果返回每页提取出25条字典信息构成的list
print(data)
return data
复制代码
这里,网页返回的 Response 是 json 格式,待提取的信息存放在其中的 data 键值中,由一段 HTML 代码构成。咱们可使用 response.json['data'] 获取该 HTML 信息,接着使用 PyQuery 搭配 CSS 语法提取出文章标题、连接、做者等所需信息。这里使用了列表生成式,可以精简代码而且转换为方便的 list 格式,便于后续存储到 MongoDB 中。咱们输出并查看一下第 2 页的提取结果:
# 由25个 dict 构成的 list
[{'title': '想要长生不老?杀死体内的“僵尸细胞”吧', 'url': 'https://www.huxiu.com/article/270086.html', 'name': '造就Talk', 'write_time': '19小时前', 'comment': '4', 'favorites': '28', 'abstract': '若是有了最终疗法,也不该该是天天都须要接受治疗'},
{'title': '日本步入下流社会,咱们还在买买买', 'url': 'https://www.huxiu.com/article/270112.html', 'name': '腾讯《你们》©', 'write_time': '20小时前', 'comment': '13', 'favorites': '142', 'abstract': '我买,故我在'}
...
]
复制代码
能够看到,成功获得所需数据,而后就能够保存了,能够选择输出为 CSV、MySQL、MongoDB 等方式,这里咱们选择保存到 MongoDB 中。
import pandas as pd
import pymongo
import time
import numpy as np
client = pymongo.MongoClient('localhost',27017)
db = client.Huxiu
mongo_collection = db.huxiu_news
def on_result(self,result):
if result:
self.save_to_mongo(result)
def save_to_mongo(self,result):
df = pd.DataFrame(result)
#print(df)
content = json.loads(df.T.to_json()).values()
if mongo_collection.insert_many(content):
print('存储到 mongondb 成功')
# 随机暂停
sleep = np.random.randint(1,5)
time.sleep(sleep)
复制代码
上面,定义了一个 on_result() 方法,该方法专门用来获取 return 的结果数据。这里用来接收上面 index_page() 返回的 data 数据,在该方法里再定义一个存储到 MongoDB 的方法就能够保存到 MongoDB 中。关于数据如何存储到 MongoDB 中,咱们在以前的 一篇文章 中有过介绍,若是忘记了能够回顾一下。
下面,咱们来测试一下整个爬取和存储过程。点击左上角的 run 就能够顺利运行单个网页的抓取、解析和存储,结果以下:
上面完成了单页面的爬取,接下来,咱们须要爬取所有 2000 余页内容。
须要修改两个地方,首先在 on_start() 方法中将 for 循环页数 3 改成 2002。改好之后,若是咱们直接点击 run ,会发现仍是只能爬取第 2 页的结果。这是由于,pyspider 以 URL的 MD5 值做为 惟一 ID 编号,ID 编号相同的话就视为同一个任务,便不会再重复爬取。因为 GET 请求的 分页URL 一般是有差别的,因此 ID 编号会不一样,也就天然可以爬取多页。但这里 POST 请求的分页 URL 是相同的,因此爬完第 2 页,后面的页数便不会再爬取。
那有没有解决办法呢? 固然是有的,咱们须要从新写下 ID 编号的生成方式,方法很简单,在 on_start() 方法前面添加下面 2 行代码便可:
def get_taskid(self,task):
return md5string(task['url']+json.dumps(task['fetch'].get('data','')))
复制代码
这样,咱们再点击 run 就可以顺利爬取 2000 页的结果了,我这里一共抓取了 49,996 条结果,耗时 2 小时左右完成。
以上,就完成了数据的获取。有了数据咱们就能够着手分析,不过这以前还需简单地进行一下数据的清洗、处理。
首先,咱们须要从 MongoDB 中读取数据,并转换为 DataFrame。
client = pymongo.MongoClient(host='localhost', port=27017)
db = client['Huxiu']
collection = db['huxiu_news']
# 将数据库数据转为DataFrame
data = pd.DataFrame(list(collection.find()))
复制代码
下面咱们看一下数据的整体状况,能够看到数据的维度是 49996 行 × 8 列。发现多了一列无用的 _id 需删除,同时 name 列有一些特殊符号,好比© 需删除。另外,数据格式所有为 Object 字符串格式,须要将 comment 和 favorites 两列更改成数值格式、 write_time 列更改成日期格式。
print(data.shape) # 查看行数和列数
print(data.info()) # 查看整体状况
print(data.head()) # 输出前5行
# 结果:
(49996, 8)
Data columns (total 8 columns):
_id 49996 non-null object
abstract 49996 non-null object
comment 49996 non-null object
favorites 49996 non-null object
name 49996 non-null object
title 49996 non-null object
url 49996 non-null object
write_time 49996 non-null object
dtypes: object(8)
_id abstract comment favorites name title url write_time
0 5bdc2 “在大家看到… 22 50 普象工业设计小站© 看了苹果屌 https:// 10小时前
1 5bdc2 中国”绿卡”号称“世界最难拿” 9 16 经济观察报© 递交材料厚 https:// 10小时前
2 5bdc2 鲜衣怒马少年时 2 13 小马宋 金庸小说陪 https:// 11小时前
3 5bdc2 预告仍是预警? 3 10 Cuba Libre 阿里即将发 https:// 11小时前
4 5bdc2 库克:咋回事? 2 3 Cuba Libre 【虎嗅早报 https:// 11小时前
复制代码
代码实现以下:
# 删除无用_id列
data.drop(['_id'],axis=1,inplace=True)
# 替换掉特殊字符©
data['name'].replace('©','',inplace=True,regex=True)
# 字符更改成数值
data = data.apply(pd.to_numeric,errors='ignore')
# 更该日期格式
data['write_time'] = data['write_time'].replace('.*前','2018-10-31',regex=True)
# 为了方便,将write_time列,包含几小时前和几天前的行,都替换为10月31日最后1天。
data['write_time'] = pd.to_datetime(data['write_time'])
复制代码
下面,咱们看一下数据是否有重复,若是有,那么须要删除。
# 判断整行是否有重复值
print(any(data.duplicated()))
# 显示True,代表有重复值,进一步提取出重复值数量
data_duplicated = data.duplicated().value_counts()
print(data_duplicated) # 显示2 True ,代表有2个重复值
# 删除重复值
data = data.drop_duplicates(keep='first')
# 删除部分行后,index中断,需从新设置index
data = data.reset_index(drop=True)
#结果:
True
False 49994
True 2
复制代码
而后,咱们再增长两列数据,一列是文章标题长度列,一列是年份列,便于后面进行分析。
data['title_length'] = data['title'].apply(len)
data['year'] = data['write_time'].dt.year
Data columns (total 9 columns):
abstract 49994 non-null object
comment 49994 non-null int64
favorites 49994 non-null int64
name 49994 non-null object
title 49994 non-null object
url 49994 non-null object
write_time 49994 non-null datetime64[ns]
title_length 49994 non-null int64
year 49994 non-null int64
复制代码
以上,就完成了基本的数据清洗处理过程,针对这 9 列数据能够开始进行分析了。
一般,数据分析主要分为四类: 「描述型分析」、「诊断型分析」「预测型分析」「规范型分析」。「描述型分析」是用来归纳、表述事物总体情况以及事物间关联、类属关系的统计方法,是这四类中最为常见的数据分析类型。经过统计处理能够简洁地用几个统计值来表示一组数据地集中性(如平均值、中位数和众数等)和离散型(反映数据的波动性大小,如方差、标准差等)。
这里,咱们主要进行描述性分析,数据主要为数值型数据(包括离散型变量和连续型变量)和文本数据。
先来看一下整体状况。
print(data.describe())
comment favorites title_length
count 49994.000000 49994.000000 49994.000000
mean 10.860203 34.081810 22.775333
std 24.085969 48.276213 9.540142
min 0.000000 0.000000 1.000000
25% 3.000000 9.000000 17.000000
50% 6.000000 19.000000 22.000000
75% 12.000000 40.000000 28.000000
max 2376.000000 1113.000000 224.000000
复制代码
这里,使用了 data.describe() 方法对数值型变量进行统计分析。从上面能够简要得出如下几个结论:
对于非数值型变量(name、write_time),使用 describe() 方法会产生另一种汇总统计。
print(data['name'].describe())
print(data['write_time'].describe())
# 结果:
count 49994
unique 3162
top 虎嗅
freq 10513
Name: name, dtype: object
count 49994
unique 2397
top 2014-07-10 00:00:00
freq 274
first 2012-04-03 00:00:00
last 2018-10-31 00:00:00
复制代码
unique 表示惟一值数量,top 表示出现次数最多的变量,freq 表示该变量出现的次数,因此能够简单得出如下几个结论:
能够看到 ,以季度为时间尺度的6 年间,前几年发文数量比较稳定,大概在1750 篇左右,个别季度数量激增到 2000 篇以上。2016 年以后文章开始增长到 2000 篇以上,可能跟网站知名度提高有关。首尾两个季度日期不全,因此数量比较少。
具体代码实现以下:
def analysis1(data):
# # 汇总统计
# print(data.describe())
# print(data['name'].describe())
# print(data['write_time'].describe())
data.set_index(data['write_time'],inplace=True)
data = data.resample('Q').count()['name'] # 以季度汇总
data = data.to_period('Q')
# 建立x,y轴标签
x = np.arange(0,len(data),1)
ax1.plot(x,data.values, #x、y坐标
color = color_line , #折线图颜色为红色
marker = 'o',markersize = 4 #标记形状、大小设置
)
ax1.set_xticks(x) # 设置x轴标签为天然数序列
ax1.set_xticklabels(data.index) # 更改x轴标签值为年份
plt.xticks(rotation=90) # 旋转90度,不至太拥挤
for x,y in zip(x,data.values):
plt.text(x,y + 10,'%.0f' %y,ha = 'center',color = colors,fontsize=fontsize_text )
# '%.0f' %y 设置标签格式不带小数
# 设置标题及横纵坐标轴标题
plt.title('虎嗅网文章数量发布变化(2012-2018)',color = colors,fontsize=fontsize_title)
plt.xlabel('时期')
plt.ylabel('文章(篇)')
plt.tight_layout() # 自动控制空白边缘
plt.savefig('虎嗅网文章数量发布变化.png',dpi=200)
plt.show()
复制代码
接下来,到了咱们比较关心的问题:几万篇文章里,到底哪些文章写得比较好或者比较火?
序号 | title | favorites | comment |
---|---|---|---|
1 | 读完这10本书,你就能站在智商鄙视链的顶端了 | 1113 | 13 |
2 | 京东打脸央视:你所谓的翻新iPhone均为正品,咱们保留向警方报案的权利 | 867 | 10 |
3 | 离职创业?先读完这22本书再说 | 860 | 9 |
4 | 货币如水,覆水难收 | 784 | 39 |
5 | 自杀经济学 | 778 | 119 |
6 | 2016年已经起飞的5只黑天鹅,都在罗振宇这份跨年演讲全文里 | 774 | 39 |
7 | 真正强大的商业分析能力是怎样炼成的? | 746 | 18 |
8 | 腾讯没有梦想 | 705 | 32 |
9 | 段永平连答53问,核心是“不为清单” | 703 | 27 |
10 | 王健林的滑铁卢 | 701 | 92 |
此处选取了「favorites」(收藏数量)做为衡量标准。毕竟,通常好的文章,咱们都会有收藏的习惯。
第一名「读完这10本书,你就能站在智商鄙视链的顶端了 」以 1113 次收藏位居第一,而且遥遥领先于后者,看来你们都怀有「想早日攀上人生巅峰,一览众人小」的想法啊。打开这篇文章的连接,文中提到了这几本书:《思考,快与慢》、《思考的技术》、《麦肯锡入职第一课:让职场新人一辈子受用的逻辑思考力》等。一本都没看过,看来这辈子是很难登上人生巅峰了。
发现两个有意思的地方。
第一,文章标题都比较短小精炼。
第二,文章收藏量虽然比较高,但评论数都很少,猜想这是由于 你们都喜欢作伸手党?
在了解文章的整体排名以后,咱们来看看历年的文章排名是怎样的。这里,每一年选取了收藏量最多的 3 篇文章。
year | title | favorites |
---|---|---|
2012 | 产品的思路——来自腾讯张小龙的分享(全版) | 187 |
Fab CEO:创办四家公司教给个人90件事 | 163 | |
张小龙:微信背后的产品观 | 162 | |
2013 | 创业者手记:我所犯的那些入门错误 | 473 |
马化腾三小时讲话实录:千亿美金这个线,其实很恐怖 | 391 | |
雕爷亲身谈:白手起家的我如何在30岁以前赚到1000万。读《MBA教不了的创富课》 | 354 | |
2014 | 85后,突变的一代 | 528 |
雕爷自述:什么是我作餐饮时琢磨、而大部分“外人”没法涉猎的思考? | 521 | |
听说这40张PPT是蚂蚁金服的内部培训资料…… | 485 | |
2015 | 读完这10本书,你就能站在智商鄙视链的顶端了 | 1113 |
京东打脸央视:你所谓的翻新iPhone均为正品,咱们保留向警方报案的权利 | 867 | |
离职创业?先读完这22本书再说 | 860 | |
2016 | 蝗虫般的刷客大军:手握千万手机号,分秒间薅干一家平台 | 554 |
准CEO必读的这20本书,你读过几本? | 548 | |
运营简史:一文读懂互联网运营的20年发展与演变 | 503 | |
2017 | 2016年已经起飞的5只黑天鹅,都在罗振宇这份跨年演讲全文里 | 774 |
真正强大的商业分析能力是怎样炼成的? | 746 | |
王健林的滑铁卢 | 701 | |
2018 | 货币如水,覆水难收 | 784 |
自杀经济学 | 778 | |
腾讯没有梦想 | 705 |
能够看到,文章收藏量基本是逐年递增的,但 2015 年的 3 篇文章的收藏量倒是最高的,包揽了总排名的前 3 名,不知道这一年的文章有什么特别之处。
以上只罗列了一小部分文章的标题,能够看到标题起地都蛮有水准的。关于标题的重要性,有这样通俗的说法:「一篇好文章,标题占一半
」,一个好的标题能够大大加强文章的传播力和吸引力。文章标题虽只有短短数十字,但要想起好,里面也是颇有不少技巧的。
好在,这里提供了 5 万个标题能够参考。如需,能够在公众号后台回复「虎嗅」获得这份 CSV 文件。
代码实现以下:
def analysis2(data):
# # 总收藏排名
# top = data.sort_values(['favorites'],ascending = False)
# # 收藏前10
# top.index = (range(1,len(top.index)+1)) # 重置index,并从1开始编号
# print(top[:10][['title','favorites','comment']])
# 按年份排名
# # 增长一列年份列
# data['year'] = data['write_time'].dt.year
def topn(data):
top = data.sort_values('favorites',ascending=False)
return top[:3]
data = data.groupby(by=['year']).apply(topn)
print(data[['title','favorites']])
# 增长每一年top123列,列依次值为一、二、3
data['add'] = 1 # 辅助
data['top'] = data.groupby(by='year')['add'].cumsum()
data_reshape = data.pivot_table(index='year',columns='top',values='favorites').reset_index()
# print(data_reshape) # ok
data_reshape.plot(
# x='year',
y=[1,2,3],
kind='bar',
width=0.3,
color=['#1362A3','#3297EA','#8EC6F5'] # 设置不一样的颜色
# title='虎嗅网历年收藏数最多的3篇文章'
)
plt.xlabel('Year')
plt.ylabel('文章收藏数量')
plt.title('历年 TOP3 文章收藏量比较',color = colors,fontsize=fontsize_title)
plt.tight_layout() # 自动控制空白边缘,以所有显示x轴名称
# plt.savefig('历年 Top3 文章收藏量比较.png',dpi=200)
plt.show()
复制代码
上面,咱们从收藏量指标进行了分析,下面,咱们关注一下发布文章的做者(我的/媒体)。前面提到发文最多的是虎嗅官方,有一万多篇文章,这里咱们筛除官媒,看看还有哪些比较高产的做者。
能够看到,前 20 名做者的发文量差距都不太大。发文比较多的有「娱乐资本论」、「Eastland」、「发条橙子」这类媒体号;也有虎嗅官网团队的做者:发条橙子、周超臣、张博文等;还有部分独立做者:伪装FBI、孙永杰等。能够尝试关注一下这些高产做者。
代码实现以下:
def analysis3(data):
data = data.groupby(data['name'])['title'].count()
data = data.sort_values(ascending=False)
# pandas 直接绘制,.invert_yaxis()颠倒顺序
data[1:21].plot(kind='barh',color=color_line).invert_yaxis()
for y,x in enumerate(list(data[1:21].values)):
plt.text(x+12,y+0.2,'%s' %round(x,1),ha='center',color=colors)
plt.xlabel('文章数量')
plt.ylabel('做者')
plt.title('发文数量最多的 TOP20 做者',color = colors,fontsize=fontsize_title)
plt.tight_layout()
plt.savefig('发文数量最多的TOP20做者.png',dpi=200)
plt.show()
复制代码
咱们关注一个做者除了是由于文章高产之外,可能更看重的是其文章水准。这里咱们选择「文章平均收藏量」(总收藏量/文章数)这个指标,来看看文章水准比较高的做者是哪些人。
这里,为了不出现「某做者只写了一篇高收藏率的文章」这种不能表明其真实水准的状况,咱们将筛选范围定在至少发布过 5 篇文章的做者们。
name | total_favorites | ariticls_num | avg_favorites |
---|---|---|---|
重读 | 1947 | 6 | 324 |
楼台 | 2302 | 8 | 287 |
彭萦 | 2487 | 9 | 276 |
曹山石 | 1187 | 5 | 237 |
饭统戴老板 | 7870 | 36 | 218 |
笔记侠 | 1586 | 8 | 198 |
辩手李慕阳 | 11989 | 62 | 193 |
李录 | 2370 | 13 | 182 |
高晓松 | 889 | 5 | 177 |
宁南山 | 2827 | 16 | 176 |
能够看到,前 10 名做者包括:遥遥领先的 重读、两位高产又有质量的 辩手李慕阳 和 饭统戴老板 ,还有大众比较熟悉的 高晓松、**宁南山 **等。
若是你将这份名单和上面那份高产做者名单进行对比,会发现他们没有出如今这个名单中。相比于数量,质量可能更重要吧。
下面,咱们就来看看排名第一的 重读 都写了哪些高收藏量文章。
order | title | favorites | write_time |
---|---|---|---|
1 | 我采访出200多万字素材,还原了阿里系崛起前传 | 231 | 2018/10/31 |
2 | 阿里史上最强人事地震回顾:中供铁军何以被生生解体 | 494 | 2018/4/9 |
3 | 马云“斩”卫哲:复原阿里史上最震撼的人事地震 | 578 | 2018/3/15 |
4 | 重读一场马云发起、针对卫哲的批斗会 | 269 | 2017/8/31 |
5 | 阿里“中供系”前世此生:马云麾下最神秘的子弟兵 | 203 | 2017/5/10 |
6 | 揭秘马云麾下最神秘的子弟兵:阿里“中供系”的前世此生 | 172 | 2017/4/26 |
竟然写的都是清一色关于马老板家的文章。
了解了前十名做者以后,咱们顺便也看看那些处于最后十名的都是哪些做者。
name | total_favorites | ariticls_num | avg_favorites |
---|---|---|---|
于斌 | 25 | 11 | 2 |
朝克图 | 33 | 23 | 1 |
东风日产 | 24 | 13 | 1 |
董晓常 | 14 | 8 | 1 |
蔡钰 | 31 | 16 | 1 |
马继华 | 12 | 11 | 1 |
angeljie | 7 | 5 | 1 |
薛开元 | 6 | 6 | 1 |
pookylee | 15 | 24 | 0 |
Yang Yemeng | 0 | 7 | 0 |
一对比,就能看到他们的文章收藏量就比较寒碜了。尤为好奇最后一位做者 Yang Yemeng ,他写了 7 篇文章,居然一个收藏都没有。
来看看他究竟写了些什么文章。
原来写的全都是英文文章,看来你们并不太钟意阅读英文类的文章啊。
具体实现代码:
def analysis4(data):
data = pd.pivot_table(data,values=['favorites'],index='name',aggfunc=[np.sum,np.size])
data['avg'] = data[('sum','favorites')]/data[('size','favorites')]
# 平均收藏数取整
# data['avg'] = data['avg'].round(decimals=1)
data['avg'] = data['avg'].astype('int')
# flatten 平铺列
data.columns = data.columns.get_level_values(0)
data.columns = ['total_favorites','ariticls_num','avg_favorites']
# 筛选出文章数至少5篇的
data=data.query('ariticls_num > 4')
data = data.sort_values(by=['avg_favorites'],ascending=False)
# # 查看平均收藏率第一名详情
# data = data.query('name == "重读"')
# # 查看平均收藏率倒数第一名详情
# data = data.query('name == "Yang Yemeng"')
# print(data[['title','favorites','write_time']])
print(data[:10]) # 前10名
print(data[-10:]) # 后10名
复制代码
说完了收藏量。下面,咱们再来看看评论数量最多的文章是哪些。
order | title | comment | favorites |
---|---|---|---|
1 | 喜瓜2.0—明星社交应用的中国式引进与创新 | 2376 | 3 |
2 | 百度,请给“儿子们”好好起个名字 | 1297 | 9 |
3 | 三星S5为何对凤凰新闻客户端下注? | 1157 | 1 |
4 | 三星Tab S:马是什么样的马?鞍又是什么样的鞍? | 951 | 0 |
5 | 三星,正在重塑你的营销观 | 914 | 1 |
6 | 马化腾,你就把微信卖给运营商得了! | 743 | 20 |
7 | 【文字直播】罗永浩 VS 王自如 网络公开辩论 | 711 | 33 |
8 | 看三星Hub如何推进数字内容消费变革 | 684 | 1 |
9 | 三星要从新定义软件与内容商店新模式,SO? | 670 | 0 |
10 | 三星Hub——数字内容交互新模式 | 611 | 0 |
基本上都是和 三星 有关的文章,这些文章大多来自 2014 年,那几年 三星 好像是挺火的,不过这两年国内基本上都见不到三星的影子了,世界变化真快。
发现了两个有意思的现象。
第一,上面关于 三星 和前面 阿里 的这些批量文章,它们「霸占」了评论和收藏榜,结合知乎上曾经的一篇关于介绍虎嗅这个网站的文章:虎嗅网实际上是这样的 ,貌似能发现些微妙的事情。
第二,这些文章评论数和收藏数两个指标几乎呈极端趋势,评论量多的文章收藏量却不多,评论量少的文章收藏量却不少。
咱们进一步观察下这两个参数的关系。
能够看到,大多数点都位于左下角,意味着这些文章收藏量和评论数都比较低。但也存在少部分位于上方和右侧的异常值,代表这些文章呈现 「多评论、少收藏」或者「少评论、多收藏」的特色。
下面,咱们再来看看文章标题的长度和收藏量之间有没有什么关系。
大体能够看出两点现象:
第一,收藏量高的文章,他们的标题都比较短(右侧的部分散点)。
第二,标题很长的文章,它们的收藏量都很是低(左边造成了一条垂直线)。
看来,文章起标题时最好不要起太长的。
实现代码以下:
def analysis5(data):
plt.scatter(
x=data['favorites'],
y =data['comment'],
s=data['title_length']/2,
)
plt.xlabel('文章收藏量')
plt.ylabel('文章评论数')
plt.title('文章标题长度与收藏量和评论数之间的关系',color = colors,fontsize=fontsize_title)
plt.tight_layout()
plt.show()
复制代码
下面,咱们看看做者在起文章标题的时候,在标点符号方面有没有什么偏好。
能够看到,五万篇文章中,大多数文章的标题是陈述性标题。三分之一(34.8%) 的文章标题使用了问号「?」,而仅有 5% 的文章用了叹号「!」。一般,问号会让人们产生好奇,从而想去点开文章;而叹号则会带来一种紧张或者压迫感,令人不太想去点开。因此,能够尝试多用问号而少用叹号。
最后,咱们从这 5 万篇文章中的标题和摘要中,来看看虎嗅网的文章主要关注的都是哪些主题领域。
这里首先运用了 jieba 分词包对标题进行了分词,而后用 WordCloud 作成了词云图,因虎嗅网含有「虎」字,故选取了一张老虎头像。(关于 jieba 和 WordCloud 两个包,以后再详细介绍)
能够看到文章的主题内容侧重于:互联网、知名公司、电商、投资这些领域。这和网站自己对外宣传的核心内容,即「关注互联网与移动互联网一系列明星公司的起落轨迹、产业潮汐的动力与趋势,以及互联网与移动互联网如何改造传统产业」大体相符合。
实现代码以下:
def analysis6(data):
text=''
for i in data['title'].values:
symbol_to_replace = '[!"#$%&\'()*+,-./:;<=>?@,。?★、…【】《》?“”‘’![\\]^_`{|}~]+'
i = re.sub(symbol_to_replace,'',i)
text+=' '.join(jieba.cut(i,cut_all=False))
d = path.dirname(__file__) if "__file__" in locals() else os.getcwd()
background_Image = np.array(Image.open(path.join(d, "tiger.png")))
font_path = 'C:\Windows\Fonts\SourceHanSansCN-Regular.otf' # 思源黑字体
# 添加stopswords
stopwords = set()
# 先运行对text进行词频统计再排序,再选择要增长的停用词
stopwords.update(['如何','怎么','一个','什么','为何','仍是','咱们','为什么','可能','不是','没有','哪些','成为','能够','背后','到底','就是','这么','不要','怎样','为了','可否','大家','还有','这样','这个','真的','那些'])
wc = WordCloud(
background_color = 'black',
font_path = font_path,
mask = background_Image,
stopwords = stopwords,
max_words = 2000,
margin =2,
max_font_size = 100,
random_state = 42,
scale = 2,
)
wc.generate_from_text(text)
process_word = WordCloud.process_text(wc, text)
# 下面是字典排序
sort = sorted(process_word.items(),key=lambda e:e[1],reverse=True) # sort为list
print(sort[:50]) # 输出前词频最高的前50个,而后筛选出不须要的stopwords,添加到前面的stopwords.update()方法中
img_colors = ImageColorGenerator(background_Image)
wc.recolor(color_func=img_colors) # 颜色跟随图片颜色
plt.imshow(wc,interpolation='bilinear')
plt.axis('off')
plt.tight_layout() # 自动控制空白边缘
plt.savefig('huxiu20.png',dpi=200)
plt.show()
复制代码
上面的关键词是这几年整体的概况,而科技互联网行业每一年的发展都是不一样的,因此,咱们再来看看历年的一些关键词,透过这些关键词看看这几年互联网行业、科技热点、知名公司都有些什么不一样变化。
能够看到每一年的关键词都有一些相同之处,但也不一样的地方:
经过这一幅图,就看出了这几年科技互联网行业、明星公司、热点信息的风云变化。
本文完。
文中的完整代码和素材能够在公众号后台回复「虎嗅」 或者在下面的连接中获取:
推荐阅读: