其实呢,当初学习python的时候,我是跟着小甲鱼老师的视频入门的,现在做爬虫.似乎当初学校学C语言的时候,我也上过鱼C论坛,真是满满的回忆啊,也越发感觉小甲鱼真的是无所不能(掰着手指数数吧,C,Python,Web前端,Linux,Java,汇编.....斗尊强者,恐怖如斯!)
近来逛着论坛,看着数不胜数的求问贴,讨论帖,展示贴,资源帖

就突然想看看这些年哪些人是真正在学习的道路上不断的进步,
同时把自己的所见所得分享给他人的,
由于论坛已经自己有了求问题满意答案的排行榜,这个我就不分析了,我打算找找作品展示,从这里入手了解一下
还是从网页分析入手

一个简单的get请求,这是个静态网页,基本除了翻页以外,没有ajax请求,而对于翻页,我们可以直接构造url的方式来请求,经过测试,发现翻页的参数只是增加了一个page参数,那很简单 翻页循环我们已经可以写出来了,而且在利用postman 测试过后,发现爬虫请求连headers都不需要,对新手还是极其友好的.
列表页请求方法

有了翻页列表以后 ,我们就可以采集数据了,我们要采集的字段如下:
- 标题
- 作者
- 时间
- 文章链接
- 作者链接

然后我们就可以愉快的把数据爬下来了,但是仔细观察一下,发现这个发帖时间上 有点和我们预想的不一样

我们来看看网页怎么写的:

可以很清晰的看到,"相对时间"比"绝对时间"多了一个<span>,而且在相对时间的<span>里有个title属性,描述了"绝对时间",这样就不需要我们自己写脚本换算了,直接利用xpath取title的值即可
需要用到的包
from lxml import etree
import random
import time
import requests
import pymysql
信息提取方法:

时间替换方法:

是不是以为我要写好长的代码来实现这个方法?
一行就搞定了哦! 自己理解,不懂的话可以评论留言.
数据库初始化以及信息存储方法:


使用前建议先准备好相关的数据库环境以及创建数据表:
CREATE TABLE `fishc` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`标题` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
`作者` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
`发表时间` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
`文章链接` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
`作者链接` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 ;
SET FOREIGN_KEY_CHECKS = 1;
这样一只爬虫就完成了

什么?这就爬完了?这就完事了?
不存在的,既然标题写了要分析数据 自然要点题啊
先上图:


这图是怎么来的呢? 当然是从我们爬到的数据分析得来,

简单的统计了一下,排列出了在[作品展示]分类中,我们的[Charles未晞]和[jerryxjr1220]吊打全场作者有吗?
读取数据库中数据方法:

柱状图方法:

饼状图方法:

第一代饼状图:

密恐福利有么有?
其实笔者本人也是在不断的学习和练习各种插件,比如一开始的柱状图,x轴名称没有完全显示,而是隔一个条显示一个名字,就很纠结,后来通过百度(花了很久时间),也算是解决了这个问题(方法在图上代码中).
最后,让我们再次感谢[Charles未晞]和[jerryxjr1220]对鱼C论坛做的卓越贡献,辛苦了!
其实还可以生成词云图片的,这个我就不折腾了,之前的文章有词云可视化,就看你们的了!
附源码(数据采集):
#!/usr/bin/env python
"""
@version: v1.0
@author: 右哼哼
@contact: 1003582810@qq.com
@site: https://fishc.com.cn
@software: PyCharm
@file: 作品展示.py
@time: 2018/9/28 6:37
"""
from lxml import etree
import random
import time
import requests
import pymysql
class FishC():
def __init__(self):
self.url = 'https://fishc.com.cn/forum.php'
# 数据库初始化
self.conn = pymysql.connect(
host='localhost',
port=3306,
user='root',
passwd='admin@123',
db='test',
charset='utf8'
)
# 创建游标
self.cursor = self.conn.cursor()
def get_html(self, page=1):
data = {
'mod': 'forumdisplay',
'fid': 173,
'filter': 'author',
'orderby': 'dateline',
'typeid': 729,
'page': page,
}
html = requests.get(self.url, params=data).text
return html
def get_info(self,html):
info = etree.HTML(html)
title = info.xpath("//table/tbody/tr/th/a[2]/text()")
author = info.xpath("//table[@id='threadlisttableid']/tbody[position()>1]/tr/td[2]//a/text()")
# 取相对时间中的绝对时间
time1 = info.xpath("//table[@id='threadlisttableid']/tbody[position()>1]/tr/td[2]//span/@title")
# 取绝对时间
time2 = info.xpath("//table[@id='threadlisttableid']/tbody[position()>1]/tr/td[2]//span/text()")
links = info.xpath("//table/tbody/tr/th/a[2]/@href")
aulinks = info.xpath("//table[@id='threadlisttableid']/tbody[position()>1]/tr/td[2]//a/@href")
# 时间处理方法,替换'昨天,前天,3天前'等日期
ctime = self.clear_info(time1,time2)
return [title,author,ctime,links,aulinks]
def clear_info(self,time1,time2):
'''时间处理'''
temp=time1+time2[len(time1):]
return temp
def save_tosql(self, data):
'''写入Mysql数据库'''
sql = "insert into fishc (标题,作者,发表时间,文章链接,作者链接) " \
"VALUES ('%s','%s','%s','%s','%s')" \
% (data[0], data[1], data[2], data[3],data[4])
try:
# 执行SQL
self.cursor.execute(sql)
self.conn.commit()
except UnicodeEncodeError as e:
print(e) # 打印错误原因
self.conn.rollback() # 回滚数据库
self.conn.close() # 关闭数据库连接
if __name__ == '__main__':
fc = FishC()
for page in range(1,18):
# 随机休眠,做一只理智的爬虫
time.sleep(random.randint(1,4))
print('第%d页'.center(20,'*') % page)
#
html = fc.get_html(page)
info = fc.get_info(html)
info_list = []
for tit, aut, tim , link, aul in zip(info[0], info[1], info[2], info[3], info[4]):
temp = [tit,aut,tim,link,aul]
info_list.append(temp)
fc.save_tosql(temp)
附源码(数据分析):
#!/usr/bin/env python
"""
@version: v1.0
@author: Mr.Q
@contact: 1003582810@qq.com
@site:
@software: PyCharm
@file: 数据分析.py
@time: 2018/9/30 7:57
"""
import pymysql
import pyecharts
class Draw():
def __init__(self):
# 数据库连接初始化
self.conn = pymysql.connect(
host='localhost',
port=3306,
user='root',
passwd='admin@123',
db='test',
charset='utf8'
)
# 创建游标
self.cursor = self.conn.cursor()
def read_data(self):
sql = "select 作者, count(*) AS count from fishc group by 作者 order by count DESC; "
self.cursor.execute(sql)
res = self.cursor.fetchall()
return res
def draw_bar(self,data):
author, count = [], []
for i in data:
author.append(i[0])
count.append(i[1])
bar = pyecharts.Bar('作品展示分析',width=1000)
bar.add('作品数量',author,count,is_more_utils=True,is_label_show=True,interval=0)
bar.render('bar.html')
def draw_pie(self,data):
less , normal, large =[], [], []
for i in data:
if i[1] <=3:
less.append(i[0])
elif i[1] <=10:
normal.append(i[0])
elif i[1] >10:
large.append(i[0])
else:
print(i)
author, count = ['1~3篇','4~10篇','10+篇'], [len(less),len(normal),len(large)]
pie = pyecharts.Pie('作品展示分布')
pie.add('', author, count, is_label_show=True)
pie.render('pie.html')
if __name__ == '__main__':
dr = Draw()
data = dr.read_data()
dr.draw_bar(data[:10])
dr.draw_pie(data)
网友评论