美文网首页Python专题
2018-09-30鱼C论坛作品展示分析(超长篇)

2018-09-30鱼C论坛作品展示分析(超长篇)

作者: 右哼哼丨左哼哼 | 来源:发表于2018-09-30 17:55 被阅读213次

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


    近来逛着论坛,看着数不胜数的求问贴,讨论帖,展示贴,资源帖


    QQ截图20180930162040.png

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


    还是从网页分析入手


    image.png

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

    列表页请求方法

    image.png

    有了翻页列表以后 ,我们就可以采集数据了,我们要采集的字段如下:

    1. 标题
    2. 作者
    3. 时间
    4. 文章链接
    5. 作者链接
    image.png

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


    image.png

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


    image.png
    可以很清晰的看到,"相对时间"比"绝对时间"多了一个<span>,而且在相对时间的<span>里有个title属性,描述了"绝对时间",这样就不需要我们自己写脚本换算了,直接利用xpath取title的值即可

    需要用到的包

    from lxml import etree
    import random
    import time
    import requests
    import pymysql
    

    信息提取方法:

    image.png

    时间替换方法:

    image.png

    是不是以为我要写好长的代码来实现这个方法?
    一行就搞定了哦! 自己理解,不懂的话可以评论留言.

    数据库初始化以及信息存储方法:

    image.png
    image.png
    使用前建议先准备好相关的数据库环境以及创建数据表:
    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;
    

    这样一只爬虫就完成了

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

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


    image.png

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

    读取数据库中数据方法:

    image.png

    柱状图方法:

    image.png

    饼状图方法:

    image.png

    第一代饼状图:

    QQ图片20180930174515.gif
    密恐福利有么有?
    其实笔者本人也是在不断的学习和练习各种插件,比如一开始的柱状图,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)
    

    相关文章

      网友评论

        本文标题:2018-09-30鱼C论坛作品展示分析(超长篇)

        本文链接:https://www.haomeiwen.com/subject/zyvwoftx.html