Python爬虫试水————爬取丽水学院百度贴吧帖子信息&分析

这周试着学了下Python

于是准备做个小爬虫练练手

——————————————————————————————

以下是爬取结果的分析:

爬取目标,百度 丽水学院 贴吧

截止至 2017年2月19号 15:30 

爬了1855个网页

共计爬取到87535条主题贴数据(贴吧总主题数共92723个 在爬取过程中因不明原因而丢失了5188个主题贴)

以下文章将主题为贴子,本文所指的贴子,全部是主题贴的意思


先来看下贴吧里发贴数量最多的人是谁吧

这个是贴吧里发贴数前20的人员 (排名第一第二的是以前贴吧可以匿名发贴时的所有人)



被回复最多的贴子是 2014年新生咨询帖 http://tieba.baidu.com/p/3120231970?pn=1  共有4402个回复信息

其次是  2016年新生咨询贴 欢迎小鲜肉们报考我校 http://tieba.baidu.com/p/4626377932?pid=92369872419&cid=103380480624#1033804806

共有3985个回复信息



接着来看下从2006年到2016年10年间的发贴情况


可以看出在2012-2015这三年发贴都比较多

2016年发贴数量极具减少,甚至少于2008年


最早的贴子,可以追溯到2006年的8月份


在2010与2011年这两年里没有一条贴子数据,一开始我以为是自己爬漏了数据,但在贴吧里翻找后,确实没有发现2010年与2011年的贴子

而且通过查找数据,发现这个断层是从 2009年的5月到 2012年的1月

期间究竟发生了什么,我也不太清楚,也许是贴吧暂时被关闭了?或者被管理删帖删完了? 不得而知





我们再来看下2016年与2015年每月的发帖情况,先看2016年


发帖数量最多的是3月份

9月份也算一个峰值,估计和新生入学有关吧



下面我们来看下2015年的发帖情况


2015年发帖数量最多的是8月份,估计是和新生开学有关


对比2015年与2016年,发现寒暑假的时候贴吧发帖数量对比平时呈现下降趋势




自己想了些关键词来模糊匹配了下

以下是统计结果


与“丽水学院” 有关的关键字最多,达到了2828个

和“吃”有关的话题还是很重要的!

“毕业” 比 “开学” 更容易成为话题

“女朋友” 提到的次数 大于 “男朋友”

“单身”比“四六级” 更重要



接下来是发帖最多的月份了

这个是发贴最多的月份前20

2012年的9月,是发帖最多的一个月



然后我们来看下一般发帖后,你会收到几个回复

这个是帖子回复数的前20 统计

可以看出,发一个贴子,一般只有10个以下的回复

4个回复的贴子占最多,有3414个

还有3205个贴子没有人回复(0)



分析到此结束

——————————————————————————————————

好了,下面是技术实现部分

一开始打算匹配字符用正则表达式来实现,但是感觉太麻烦。

后来经Robinson推荐,选用lxml库里的 xPath 来实现

但是一直不成功

后来发现是坑爹的百度贴吧为了防止xpath,把帖子的主体部分给注释掉了,估计在浏览器里打开的时候用了某些

奇技淫巧把帖子还原了出来。

但是一般request请求并不会解析与执行 js里的内容,所以xpath 在这里是不能用的


于是又用回了正则表达式

匹配了好久,终于弄好了

然后又是连接数据库,写入数据库。。

但是某些帖子的标题里是含有emoji的

所以要把原本设置的 utf8 格式数据库 改为utf8mb4 格式


总之出了很多岔子。。


总结下,Python是一个很容易上手的语言,我周五下午才开始自学这个语言,当天晚上就写了一个抓去一个网页里所有图片的小程序。可以说,Python 入门简单,但想深入,比较难


下面是源代码地址:https://github.com/xiaoshidefeng/crawler/blob/master/postcrawler/PostCrawler.py

感兴趣的人可以拿去玩玩。。


再在这里贴下代码吧

import re
import urllib.request

import pymysql

#打开数据库连接
import sys

import time

print("连接数据库...")
db = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='POSTINFO', charset='utf8mb4')
print("数据库连接成功")
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()

#存在就删表重建
cursor.execute("DROP TABLE IF EXISTS POSTINFOS")

# 创建表
sql = """CREATE TABLE POSTINFOS (
         ID INT NOT NULL AUTO_INCREMENT,
         POST_REPLY_NUM TEXT,
         POST_TITLE TEXT,
         POST_AUTHOR TEXT,
         POST_CREAT_TIME TEXT,
         PRIMARY KEY (ID))"""

cursor.execute(sql)

def insert(replynum,posttitle,postauthor,creattime):
    sqlorder = """INSERT INTO POSTINFO(POST_REPLY_NUM,POST_TITLE,POST_AUTHOR,POST_CREAT_TIME) VALUES ('"""+replynum+"'"+","+"'"+posttitle+"'"+","+"'"+postauthor+"'"+","+"'"+creattime+"')"
    try:
        # 执行sql语句
        cursor.execute(sqlorder)
        # 提交到数据库执行
        db.commit()
        print("数据库写入成功")
    except:
        # 如果发生错误
        print("数据库写入失败")

if __name__ == "__main__":
    pageurl = ''
    pageurl = input("是否开始爬取数据(y/n)")
    if(pageurl=='n'):
        sys.exit(0)
    pagenum = 0

    initial_page = "http://tieba.baidu.com/f?kw=%E4%B8%BD%E6%B0%B4%E5%AD%A6%E9%99%A2&ie=utf-8&pn="
    webheader = {
              'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '                            'Chrome/51.0.2704.63 Safari/537.36'
           }
    while pagenum<=92700:
        newpage = initial_page + str(pagenum)
        req = urllib.request.Request(url=newpage, headers=webheader)
        webPage = urllib.request.urlopen(req)
        contentBytes = webPage.read()
        contentBytes = contentBytes.decode('UTF-8')

        for onepost in set(re.findall( r'<div class="col2_left j_threadlist_li_left">(.*?)<div class="threadlist_detail clearfix">', str(contentBytes), re.S)):  # 正则表达式找图
            replyNumber = re.findall( r'title="回复">(.*?)</span>', onepost , re.S)
            postTitle = re.findall( r'<a href=".*?" title="(.*?)" target="_blank"', onepost , re.S)
            postAuthor = re.findall( r'title="主题作者:(.*?)"', onepost , re.S)
            postCreatTime = re.findall( r'title="创建时间">(.*?)</span>', onepost , re.S)

            print("回复时间:"+replyNumber[0])
            print("帖子标题:" + postTitle[0])
            print("帖子作者:" + postAuthor[0])
            print("创建时间:" + postCreatTime[0])
            insert(replyNumber[0],postTitle[0],postAuthor[0],postCreatTime[0])
            print("---------------------------------")
        print("开始休眠")
        time.sleep(3)
        print("休眠结束")
        print("---------------------------------")
        pagenum=pagenum+50

    print("数据抓取完毕 程序运行结束")
# 关闭数据库连接
db.close()



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值