运行环境:
Python3.6
、Pycharm2017.2
、Windows10 RS4
GitHub地址:https://github.com/IMWoolei/CSDN_GetRange
前言
我的CSDN
博客是今年八月份才开始写的,写博客的主要目的是对近期学习的知识点进行总结。在写博客的过程中也开始关注博客访问量、排名等等信息。
因为正在练习爬虫技巧,所以我写了一个爬虫程序来获取我的CSDN
博客访问量、排名、原创文章数、评论数这四个信息。
- 初级目标是将其存入
json
或csv
文件中 - 最终目标是通过将收集的数据可视化来查看其关系。
正文
获取CSDN
访问量、排名等信息
- 我们通过电脑浏览器任意一篇
CSDN
博文,发现如果不是排名靠前的博客排名上显示的是千里之外,而不是具体的排名名次。但是在移动端显示时能够正常显示名次,所以这次我爬取的是移动端的网页。
- 为了方便将获取的信息存储并访问,所以将其存入
json
文件中,json
的数据格式和字典dict
类型一致,所以调用访问极为方便。
获取信息代码示例
from urllib.request import Request, urlopen
from bs4 import BeautifulSoup
url = 'http://m.blog.csdn.net/IMW_MG' # 移动端即为子域名m.blog.csdn.net
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}
request = Request(url, headers=header)
response = urlopen(request)
bsObj = BeautifulSoup(response, 'lxml')
info_list = bsObj.find('ul', {'class': 'personal_list'}).findAll('li') # 需要获取的信息全部存在于<ul></ul>标签中
info_dict = {}
for item in info_list:
info_dict[item.find('span').get_text()] = int(item.find('em').get_text())
print(info_dict)
# 运行结果
{'访问': 19836, '排名': 70241, '原创': 46, '评论': 8}
将获取信息存入json
文件中
将获取信息存入json
文件中完整代码
from urllib.request import Request, urlopen
from bs4 import BeautifulSoup
import json
import time
# 获取当前访问量
def getInfo():
url = 'http://m.blog.csdn.net/IMW_MG' # 移动端即为子域名m.blog.csdn.net
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}
request = Request(url, headers=header)
response = urlopen(request)
bsObj = BeautifulSoup(response, 'lxml')
info_list = bsObj.find('ul', {'class': 'personal_list'}).findAll('li')
info_dict = {}
for item in info_list:
info_dict[item.find('span').get_text()] = int(item.find('em').get_text())
return info_dict
# 12-02 凌晨更新:之前写入文本的是错误的JSON格式,现在做了一些修改
def writeData():
# global info_time
# info_time = {}
fmt = "%Y-%m-%d %H:%M" # 格式化时间显示
info_dict = getInfo()
info_time[time.strftime(fmt, time.localtime())] = info_dict
print(info_time)
info_json = json.dumps(info_time, ensure_ascii=False)
with open('CSDN_info.json', 'w', encoding='utf8') as json_file: # 注意编码问题,否则中文无法正常显示
json_file.write(info_json)
json_file.close()
if __name__ == "__main__":
writeData()
为了获取访问量、排名信息走势,所以必然应该长时间定时获取博客信息。
所以我们应该将该程序定时执行,定时执行又分两种:
直接修改代码定时执行相关代码块
循环+延时,也是最简单粗暴的,可以在
__main__
引用模块中修改为如下:if __name__ == "__main__": import sys, time count = 1 while True: try: print("第 %d 次获取排名信息" % count) writeData() count += 1 time.sleep(60) except Exception: print('产生出错,获取信息终止') sys.exit()
用
sched
来定时执行任务【链接】- 直接使用
time
模块定时执行 - ….
在系统中执行脚本使其定时执行
- 在
Linux
系统中可以向crontab
中添加任务来做到定时执行,比如在我的树莓派Linux
系统中编辑vim /etc/crontab
,在其末尾加入以下任务:
# 10分钟执行一次py代码,并将产生信息存入Run.log文件中, 10 * * * * root /usr/bin/python3 /home/pi/Desktop/CSDN/CSDN_Info.py > /home/pi/Desktop/CSDN_Info/Run.log
# 使定时任务生效 sudo /etc/init.d/cron restart
- 在
Windows
系统中创建Python
定时任务可以参考这篇博客【链接】
- 在
收集数据可视化
关于数据可视化这一块,其实就是想把上面得到的数据绘制成折线图。
折线图的绘制我用到的是matplotlib
模块,早就听说这个模块功能的强大,尝试了一下果然还是不太好入门,一下午的时间在设置x
轴字体大小上差点弄到崩溃,所以我就弄了点皮毛现学现卖。
在使用
matplotlib
模块绘制图表可以参考以下两篇博文:
– 使用Python matplotlib
绘制股票走势图:http://www.jdon.com/idea/matplotlib.html
–python
使用matplotlib
绘制折线图教程:http://www.jb51.net/article/104916.htm
首先附上完整代码
from urllib.request import Request, urlopen
from bs4 import BeautifulSoup
from pylab import *
import matplotlib.pyplot as plt
import json
import time
import sys
# 获取当前访问量
def getInfo():
url = 'http://m.blog.csdn.net/IMW_MG'
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}
request = Request(url, headers=header)
response = urlopen(request)
bsObj = BeautifulSoup(response, 'lxml')
info_list = bsObj.find('ul', {'class': 'personal_list'}).findAll('li')
info_dict = {}
for item in info_list:
info_dict[item.find('span').get_text()] = int(item.find('em').get_text())
return info_dict
def writeData():
# global info_time
# info_time = {}
fmt = "%Y-%m-%d %H:%M" # 格式化时间显示
info_dict = getInfo()
info_time[time.strftime(fmt, time.localtime())] = info_dict
print(info_time)
info_json = json.dumps(info_time, ensure_ascii=False)
with open('CSDN_info.json', 'w', encoding='utf8') as json_file: # 注意编码问题,否则中文无法正常显示
json_file.write(info_json)
print(info_json)
json_file.close()
def drawChart(filename):
matplotlib.use('Agg')
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体,否则中文显示乱码
with open(filename, 'r', encoding='utf8') as file:
info_time = json.loads(file) # 读取json数据
# 因为不懂matplotllib,所以只好获取列表来绘制
date = [] # 用于存时间
view_coun = [] # 用于存访问量
ranking_coun = [] # 用于存放排名
article_coun = [] # 存放原创文章数
comment_coun = [] # 评论数
for key in info_time.keys():
date.append(key)
view_coun.append(info_time[key]['访问'])
ranking_coun.append(info_time[key]['排名'])
article_coun.append(info_time[key]['原创'])
comment_coun.append(info_time[key]['评论'])
fig = plt.figure(figsize=(20, 7)) # 设置图表大小
fig.suptitle('我的CSDN博客信息\n', fontsize=18, fontweight='bold') # 设置图表大标题(18号、加粗)
axes_view = fig.add_subplot(1, 3, 1) # 第一个子图表,绘制访问量
axes_ranking = fig.add_subplot(1, 3, 2) # 第二个子图表,绘制名次信息
axes_article = fig.add_subplot(1, 3, 3) # 第三个子图表,绘制文章原创数变化
# axes_comment = fig.add_subplot(2, 2, 4)
# 下面绘制子图表的代码冗余得无法入目,时间太晚了,先做到实现基本功能,之后再继续更新优化
axes_view.set_title('访问量变化') # 设置子图表标题
for label in axes_view.xaxis.get_ticklabels(): # 每一个x轴标签设置倾斜30度以方便查看
label.set_rotation(30)
axes_view.set_ylabel('访问量', fontsize=9) # 设置y轴
axes_view.plot(date, view_coun, marker='o', mec='r', mfc='w') # 绘制折线并设置样式
axes_ranking.set_title('排名变化')
for label in axes_ranking.xaxis.get_ticklabels():
label.set_rotation(30)
axes_ranking.set_ylabel('访问量', fontsize=9)
axes_ranking.plot(date, ranking_coun, marker='*', mec='r', mfc='w')
axes_article.set_title('原创文章变化')
for label in axes_article.xaxis.get_ticklabels():
label.set_rotation(30)
axes_view.set_ylabel('访问量', fontsize=9)
axes_article.plot(date, article_coun, marker='v', mec='r', mfc='w')
fig.savefig('我的CSDN博客信息.jpg') # 将绘制的图表保存
# plt.show()
if __name__ == "__main__":
count = 1
info_time = {} # 创建一个全局字典变量用于存储信息
while True:
try:
print("第 %d 次获取排名信息" % count)
writeData()
time.sleep(3600)
drawChart('CSDN_Info.json') # 绘制json文件中信息的图表
count += 1
time.sleep(3600)
except Exception:
print('产生出错,获取信息终止')
sys.exit()
效果展示
获取的JSON数据效果展示
生成的折线图效果展示
简单的数据分析
- 最后也来分析一下吧,虽然说单天的数据不具有完全的代表性
- 访问量增长幅度最快的还是白天,早上6:00之后增长速度大于深夜的增长速度,这也是符合常理的,毕竟晚上还翻CSDN的人是少数。
- 原创文章的增加会带来访问量的变化,在文章数越多的情况下,这种变化越不明显。
- 排名更新较慢,到了晚上才更新了一次排名信息