关于博客访问量的问题, 影响因素有很多, 例如你的权重, 你的博客数量, 包括你的标题是否吸引人都是一个衡量的标准.
这些东西需要的是日积月累, 今天我们从其中的一个维度入手: 发帖时间. 相信大家都明白, 不论是 csdn, 博客园这种技术博客
还是今日头条百度贴吧或者抖音快手这种娱乐论坛, 都有自己的在线高峰期. 例如百度贴吧, 用户年龄段普遍偏小,"夜猫子" 占据主力.
21-23 点是在线高峰期, 这个时间的阅读量以及评论量也是最多的, 自媒体人肯定会选择在这个时间发帖已得到更多的阅读及评论.
那我们的博客园呢? 目前我们还不知道, 既然园子里面都是程序猿, 数据统计咱就要拿出点技术人员该有的样子, 接下来我们
写一个爬虫统计所有的发帖时间以及阅读数量.
所需语言:
- python
- c#
- sql server
爬取数据
我们打开博客园首页, 首页的文章列表有发帖时间, 阅读数, 博客园最多只有 200 页, 我们只要将这 200 页的所有文章阅读数, 发帖时间爬取到就 ok.
下面我们用 python+scrapy 来编写爬虫代码.
环境配置:
pip install scrapy 安装爬虫框架, scrapy 安装容易遇到坑, scrapy 教程与常见坑 http://www.runoob.com/w3cnote/scrapy-detail.html , 不懂 scrapy 看链接.
scrapy startproject csblog 创建项目
scrapy gensider scblogSpider "csblogs.com" 创建爬虫文件
修改 csblog 下面的 items.py
title: 文章标题
read: 阅读数
date: 发帖时间
- # -*- coding: utf-8 -*-
- # Define here the models for your scraped items
- #
- # See documentation in:
- # https://doc.scrapy.org/en/latest/topics/items.html
- import scrapy
- class CnblogsItem(scrapy.Item):
- title = scrapy.Field()
- read = scrapy.Field()
- date = scrapy.Field()
然后我们编写爬虫代码, 首先审查下首页的 HTML 结构.
首先吐槽下翻页遇到的坑, https://www.cnblogs.com/#p4, 表面看上去 #p4 是页码, 但是多次尝试变化页码爬取, 都无效果, 始终为第一页.
经过调试工具查看请求才发现, 这个 url 是被重写过得, 想要翻页得这么发请求.
接下来就容易多了, 向这个地址发请求, 在返回的 HTML 中取得相应的数据就好了, 贴代码.
- # -*- coding: utf-8 -*-
- import scrapy
- from cnblogs.items import CnblogsItem
- class CsblogSpider(scrapy.Spider):
- name = 'csblog'
- allowed_domains = ['cnblogs.com']
- start_urls= ['https://www.cnblogs.com/mvc/AggSite/PostList.aspx']
- PageIndex = 1
- def start_requests(self):
- url = self.start_urls[0]
- #因为博客园只允许 200 页
- for each in range(1,200):
- print("抓取页码")
- print(each)
- post_data ={
- 'CategoryId':'808',
- 'CategoryType':"SiteHome",
- 'ItemListActionName':"PostList",
- 'PageIndex':str(each),
- 'ParentCategoryId':'0',
- 'TotalPostCount':'400'
- }
- yield scrapy.FormRequest(url=url, formdata=post_data)
- def parse(self, response):
- items = []
- #所有文章都在 < div class="post_item">中
- for each in response.xpath("/html/body/div[@class='post_item']"):
- #提取标题
- title = each.xpath('div[@class="post_item_body"]/h3/a/text()').extract()
- #提取发布日期
- date = each.xpath('div[@class="post_item_body"]/div/text()').extract()
- #提取阅读数
- read = each.xpath('div[@class="post_item_body"]/div/span[@class="article_view"]/a/text()').extract()
- title = title[0]
- #去除无用的字符
- date = str(date).replace("[' \\r\\n ',' \\r\\n",'').replace("\\r\\n']","").replace("发布于","").lstrip()
- read = read[0].replace("阅读(","").replace(")","")
- item = CnblogsItem()
- item['title'] = title
- item['read'] = read
- item['date'] = date
- items.append(item)
- return items
爬虫的代码很简单, 这也是 python 的强大之处.
运行 scrapy crawl csblog -o data.xml 将爬取到的数据保存为 xml.
我们已经将抓取到的数据保存到本地 xml 了, 接下来要做的事情就是数据统计了. 所谓 "术业有专攻", 做统计没有比 sql 更强大的语言了, python 的任务到此结束.
数据存储
为了方便的对数据进项统计查询, 我们把 xml 保存到 MS Sql Server 中, 做个这个事情没有比 Sql server 的老伙计 C# 更合适的了, 没啥好说的简简单单的几个方法.
- static void Main(string[] args)
- {
- data d = (data)Deserialize(typeof(data), File.OpenRead(@"D:/MyCode/cnblogs/cnblogs/data.xml"));
- DataTable dt = ToDataTable<data.item>(d.items);
- dt.TableName = "t_article";
- dt.Columns.Remove("date");
- SqlHelper.ExecuteNonQuery(dt);
- }
- /// <summary>
- /// Convert a List{T} to a DataTable.
- /// </summary>
- private static DataTable ToDataTable<T>(List<T> items)
- {
- var tb = new DataTable(typeof(T).Name);
- PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
- foreach (PropertyInfo prop in props)
- {
- Type t = GetCoreType(prop.PropertyType);
- tb.Columns.Add(prop.Name, t);
- }
- foreach (T item in items)
- {
- var values = new object[props.Length];
- for (int i = 0; i <props.Length; i++)
- {
- values[i] = props[i].GetValue(item, null);
- }
- tb.Rows.Add(values);
- }
- return tb;
- }
- /// <summary>
- /// Determine of specified type is nullable
- /// </summary>
- public static bool IsNullable(Type t)
- {
- return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
- }
- /// <summary>
- /// Return underlying type if type is Nullable otherwise return the type
- /// </summary>
- public static Type GetCoreType(Type t)
- {
- if (t != null && IsNullable(t))
- {
- if (!t.IsValueType)
- {
- return t;
- }
- else
- {
- return Nullable.GetUnderlyingType(t);
- }
- }
- else
- {
- return t;
- }
- }
- /// 反序列化
- /// </summary>
- /// <param name="type"></param>
- /// <param name="xml"></param>
- /// <returns></returns>
- public static object Deserialize(Type type, Stream stream)
- {
- XmlSerializer xmldes = new XmlSerializer(type);
- return xmldes.Deserialize(stream);
- }
数据已经成功的存储到 sql server, 接下来的数据统计是重头戏了.
数据统计
--200 页码帖子总数量
select COUNT(*) from t_article
-- 查询的哪个时间段阅读量最多
-- 查询结果显示早 9 点阅读量是最多的, 并不意外
-- 而早 6 点 (5180) 与 7 点 (55144) 相差了近 10 倍
--7 点与 8 点相比差了也有三倍, 这说明程序猿们陆续
-- 开始上班了, 上班敲代码一定是查资料的高峰期,
-- 果不其然, 8,9,10,11,15,16 是阅读量最高峰的几个时间段
-- 都分布在上班时间, 而出乎意料的事 22 点的阅读量也不低
-- 看来程序猿们回家后也很努力的嘛(应该是在加班)
- select
- CONVERT(INT, CONVERT(varchar(2),time, 108)) as count,
- SUM([read]) as [read]
- from t_article
- group by
- CONVERT(INT, CONVERT(varchar(2),time, 108))
- order by [read] desc
-- 查询阅读量在一个星期内的分布情况
-- 结果一点都不意外, 星期三比另六天
-- 高得多, 星期一到星期五是工作日
-- 每天的阅读量都很高, 周末阅读量下滑
-- 的厉害, 因为休息了嘛(居然没在加班)
- select
- datename(weekday, time) as weekday,
- SUM([read]) as [read]
- from t_article
- group by
- datename(weekday, time)
- order by [read] desc
-- 按照阅读数量排行
-- 阅读数量与发帖时间基本成正比
-- 这意味着, 你辛辛苦苦写的文章
-- 没人看, 没有关系. 时间不会辜负你
- select
- CONVERT(varchar(100), time, 111),
- sum([read])
- from t_article
- group by CONVERT(varchar(100), time, 111)
- order by sum([read])
总结
阅读的最高峰时段是早 9 点, 所以这也是发帖的最优时间, 8,9,10 都是不错的时间, 如果你想要更多的阅读, 不要错过呦.
阅读数量最少的是星期六跟星期日, 这两天可以不用发帖了, 可以给自己放个假.
阅读数量会随着时间慢慢变多, 也就是说一开始没有阅读也没关系, 只要帖子里有干货, 随着时间推移依然还会有许多阅读从搜索引擎跳转过来, 阅读量会慢慢上去的.
源码以及数据库下载地址 https://pan.baidu.com/s/11c0QV5mByK4uhgv2Jh53Xg
来源: https://www.cnblogs.com/abountme/p/10300737.html