朴素贝叶斯趣味挑战项目

1.目的

  定时爬取笑话网站,利用朴素贝叶斯分析,将不同笑话发给不同人群。

2.方案

  (1)首先利用python爬虫抓取某个网站上的笑话。

   (2)之后利用windows系统的任务计划程序功能早上8点定时执行此python爬虫。因为不可能一直开着电脑,所以用云服务器。

   (3)然后用朴素贝叶斯模型来判断当前的笑话是否属于成人笑话。

   (4)如果是成人笑话,用爬虫把它自动发给好兄弟的qq邮箱。

   (5)如果不是成人笑话,用爬虫把它自动发给女朋友的qq邮箱。

3.实施

  1.选取合适的笑话网站。---- 某某网站。

   2.学习爬虫,本来只会RSS源那样子爬,但是好多网站找不到RSS地址,所以我只能学习爬虫。

      (其实最后也没用到抓包工具,可以先不下载)首先需要抓包工具,下载火狐浏览器的低版本才能兼容httpfox,下载地址http://ftp.mozilla.org/pub/firefox/releases/35.0/win32/zh-CN/,这个是中文版

      首先入门爬虫,https://cuiqingcai.com/1052.html,学长推荐的课程,开始入门。

      这门课程上的是Python2,关于其中的函数的差别,http://blog.csdn.net/duxu24/article/details/77414298

首先以post的方式爬取一个不需要验证码的 

import urllib.request
import urllib.parse

values = {"username":"[email protected]","password":"xxxxx"}
data = urllib.parse.urlencode(values).encode(‘utf-8‘)
url = "http://nian.so/"
request = urllib.request.Request(url,data)
response = urllib.request.urlopen(request)
print(response.read())

  3.记录一下cookie学习的代码。

  1)利用CookieJar对象实现获取cookie的功能,并存储到变量中,打印变量。

import urllib.request
import urllib.parse
import urllib.error
import http.cookiejar

cookie = http.cookiejar.CookieJar() #声明一个CookieJar对象实例来保存cookie
#使用HTTPCookieProcessor创建cookie处理器,并以其为参数构建opener对象
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
#构建请求
respoense = opener.open("http://www.baidu.com")
for item in cookie:
    print(‘Name = ‘,item.name)
    print(‘Value = ‘,item.value)

  2)保存Cookie到文件,用MozillaCookieJar模块

import urllib.request
import urllib.parse
import urllib.error
import http.cookiejar

filename = "F:\\cookie.txt"
cookie = http.cookiejar.MozillaCookieJar(filename) #声明一个CookieJar对象实例来保存cookie
#使用HTTPCookieProcessor创建cookie处理器,并以其为参数构建opener对象
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
#构建请求
respoense = opener.open("http://www.baidu.com")
#保存cookie到文件
cookie.save(ignore_discard=True,ignore_expires=True)

  ignore_discard的意思是即使cookies将被丢弃也将它保存下来,ignore_expires的意思是如果在该文件中cookies已经存在,则覆盖原文件写入。

  打开cookie文件。

  

  3)从文件中获取Cookie并访问

import urllib.request
import http.cookiejar

filename = "F:\\cookie.txt"
cookie = http.cookiejar.MozillaCookieJar() #声明一个CookieJar对象实例来保存cookie
#使用HTTPCookieProcessor创建cookie处理器,并以其为参数构建opener对象
cookie.load(filename,ignore_discard=True,ignore_expires=True)
request = urllib.request.Request("http://www.baidu.com")
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
#构建请求
response = opener.open(request)
print(response.readline())

   4)利用cookie模拟网站登录

     访问我校教务系统。

import urllib.request
import http.cookiejar

filename = "F:\\cookie.txt"
cookie = http.cookiejar.MozillaCookieJar(filename) #声明一个CookieJar对象实例来保存cookie
#使用HTTPCookieProcessor创建cookie处理器,并以其为参数构建opener对象
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
#构建请求
loginUrl = "http://ids.chd.edu.cn/authserver/login?service=http%3A%2F%2Fportal.chd.edu.cn%2F"
values = {"username":"201524070201","password":"xxxxxx"}
data = urllib.parse.urlencode(values).encode(‘utf-8‘)
respoense = opener.open(loginUrl,data)
#保存cookie到文件
cookie.save(ignore_discard=True,ignore_expires=True)
gradeUrl = "http://bkjw.chd.edu.cn/eams/teach/grade/course/person!search.action?semesterId=75&projectType="
result = opener.open(gradeUrl)
print(result.read())

  4.记录正则表达式学习过程中的一点小问题。

   我把学习正则的python文件命名为re.py,结果说module ‘re‘ has no attribute ‘match‘,结果一百度

   命名py脚本时,不要与python预留字,模块名等相同,即Python文件名不要使用Python系统库的名字,就是因为使用了Python系统库的名字,

   所以在编译的时候才会产生.pyc文件。正常的Python文件在编译运行的时候是不会产生.pyc文件的!

   这类问题的解决方法则是:更改python脚本的命名,不要与python系统库重合即可。回答链接:https://www.cnblogs.com/fangxx/p/xx-python02.html

  5.正式学习爬取某笑话网站。

   学习崔庆才大神的爬取记录,还有后人更改py2为py3的博客,进行学习。

   1)目标。

    (1)抓取糗事百科热门段子。

    (2)过滤袋有图片的段子。

    (3)根据发布时间,段子内容,点赞数,进行筛选。

   2)确定URL并抓取页面代码。

import urllib.request
import urllib.error
#不需要用到cookie
#构建请求
page = 1
url = "https://www.qiushibaike.com/hot/page/" + str(page)
header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36"
}
try:
    request = urllib.request.Request(url,headers=header)
    response = urllib.request.urlopen(request)
    print(response.read().decode("utf-8"))
except urllib.error.URLError as e:
    if hasattr(e,"code"):
        print(e.code)
    if hasattr(e,"reason"):
        print(e.reason)

    提取到的内容如图所示。

    3)加入正则表达式提取第一页的所有段子。

      先写正则表达式。

    正则表达式如下:

        #0发布人 1内容 2是图片 3是点赞数
        pattern = re.compile(‘‘‘<div class="article.*?<h2>(.*?)</h2>.*?‘‘‘
                             + ‘‘‘<span>(.*?)</span>.*?‘‘‘
                             + ‘‘‘<!-- 图片或gif -->(.*?)<div class="stats">.*?‘‘‘
                             + ‘‘‘<span class="stats-vote"><i class="number">(.*?)</i>‘‘‘, re.S)    

     正则表达式在写的时候,一定要注意空格!!!  <!-- 图片或gif --> 里面的空格害我找了很长时间。

   4)获取笑话。

    过滤掉带图片的。

import urllib.request
import urllib.error
import re

def init():
    #不需要用到cookie
    #构建请求
    page = 1
    url = "https://www.qiushibaike.com/hot/page/" + str(page)
    header = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36"
    }
    try:
        request = urllib.request.Request(url,headers=header)
        response = urllib.request.urlopen(request)
        content = response.read().decode("utf-8")
        #0发布人 1内容 2是图片 3是点赞数
        pattern = re.compile(‘‘‘<div class="article.*?<h2>(.*?)</h2>.*?‘‘‘
                             + ‘‘‘<span>(.*?)</span>.*?‘‘‘
                             + ‘‘‘<!-- 图片或gif -->(.*?)<div class="stats">.*?‘‘‘
                             + ‘‘‘<span class="stats-vote"><i class="number">(.*?)</i>‘‘‘, re.S)
        items = re.findall(pattern,content)
        #只要没图片的段子
        for item in items:
            if not re.search("img",item[2]):
                result = re.sub(‘<br/>‘,"\n",item[1])
                print("发布人: %s\n内容:%s\n点赞数:%s\n" %(item[0].strip(),item[1].strip(),item[3].strip()))
    except urllib.error.URLError as e:
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)

init()
#<div class="content">

    把那种查看全文的显示全。

    获取段子完整代码。其中遇到的问题:http://www.cnblogs.com/littlepear/p/8456897.html

import urllib.request
import urllib.error
import re
page = 5
url = "https://www.qiushibaike.com/hot/page/"
mainurl = "https://www.qiushibaike.com"
header = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36"
    }
def init():
    content = getpage(index = page)
    #0发布人 1内容 2是图片 3是点赞数
    pattern = re.compile(‘‘‘<div class="article.*?<h2>(.*?)</h2>.*?‘‘‘
                         + ‘‘‘<a href="(.*?)".*?‘‘‘
                         + ‘‘‘<span>(.*?)</span>.*?‘‘‘
                         + ‘‘‘<!-- 图片或gif -->(.*?)<div class="stats">.*?‘‘‘
                         + ‘‘‘<span class="stats-vote"><i class="number">(.*?)</i>‘‘‘, re.S)
    items = re.finditer(pattern,content)
    pageItems = []
    #只要没图片的段子
    for item in items:
        zannum = int(item.group(5).strip())
        if ((not re.search("img",item.group(4))) and (zannum>1000)):
            #print(zannum) 挑选赞大于1000的笑话
            #print(item.group())
            if ((not re.search("查看全文",item.group()))):
                result = re.sub("<br/>","\n",item.group(3))
                #print("发布人: %s\n内容:%s\n点赞数:%s\n" %(item.group(1).strip(),result.strip(),item.group(5).strip()))
                pageItems.append([item.group(1).strip(),result.strip(),item.group(5).strip()])
            else:
                contentForAll = getpage(contentUrl=item.group(2))
                patternForAll = re.compile(‘‘‘<div class="article.*?<h2>(.*?)</h2>.*?‘‘‘
                    + ‘‘‘<div class="content">(.*?)</div>.*?‘‘‘
                    + ‘‘‘<span class="stats-vote"><i class="number">(.*?)</i>‘‘‘,re.S)
                # patternForAll = re.compile(‘‘‘<div class="article.*?<h2>(.*?)</h2>‘‘‘
                #                                + ‘‘‘.*?<div class="content">(.*?)</div>‘‘‘
                #                                + ‘‘‘.*?<i class="number">(.*?)</i>‘‘‘, re.S)
                newitems = re.findall(patternForAll,contentForAll)
                result = re.sub("<br/>","\n",newitems[0][1])
                #print("发布人: %s\n内容:%s\n点赞数:%s\n" %(newitems[0][0].strip(),result.strip(),newitems[0][2].strip()))
                pageItems.append([newitems[0][0].strip(),result.strip(),newitems[0][2].strip()])
    return pageItems
def getpage(index=None,contentUrl=None):
    response = None
    if index:
        request = urllib.request.Request(url + str(index),headers=header)
        response = urllib.request.urlopen(request)
    elif contentUrl:
        request = urllib.request.Request(mainurl + contentUrl,headers=header)
        response = urllib.request.urlopen(request)
    return response.read().decode("utf-8")
def main():
    pageItems = []
    pageItems = init()
    for jokelist in pageItems:
        for content in jokelist:
            print(content)
main()

    效果:

   6.通过朴素贝叶斯判断是成人笑话还是普通笑话。

    用了一份停用表,感觉效果还很好。

    之前与之后的对比:

    关于朴素贝叶斯的写法与推导,在之前的博客上:http://www.cnblogs.com/littlepear/p/8322251.html

     同时关于汉字的处理,参考:https://www.cnblogs.com/marc01in/p/4775440.html

   

from numpy import *

#加载停用词
stop_word = []
def loadword(text):
    word = []
    fr = open(text,‘r‘)
    lines = fr.readlines()
    for line in lines:
        word.extend(line.strip())
    fr.close()
    return word

def bagOfWordsVec(vocabSet,inputSet):
    returnVec = [0]*len(vocabSet)
    for word in inputSet:
        if word in vocabSet:
            returnVec[vocabSet.index(word)] += 1
    return returnVec

def textParse(bigString,stop_word):
    listOfWord = []
    #print(stop_word)
    for word in bigString:
        if word not in stop_word:
            listOfWord.append(word)
    return listOfWord

#创建一个词汇的集合
def createVocabList(dataSet):
    vocabSet = set([]) #创建空集合
    for document in dataSet:
        vocabSet |= set(document)
    return list(vocabSet)

def trainNB0(trainMatrix,trainCategory):
    numTrainDocs = len(trainMatrix) #有几行话
    numWords = len(trainMatrix[0]) #每行的词汇表的词数
    # print(numTrainDocs)
    # print(numWords)
    pAbusive = sum(trainCategory)/float(numTrainDocs) #p(Ci) 算是垃圾邮件的概率
    p0Num = ones(numWords)
    p1Num = ones(numWords)
    # print(p0Num)
    #p0Denom = 2.0; p1Denom = 2.0 #书上是2.0 不知道为什么 p(x1|c1)= (n1 + 1) / (n + N)  看网上的,
    #为了凑成概率和是1,N应该是numWords
    p0Denom = 1.0*numWords; p1Denom = 1.0*numWords
    for i in range(numTrainDocs):
        if trainCategory[i] == 1:
            #某句话是侮辱性的话
            p1Num += trainMatrix[i] #矩阵相加
            #print(p1Num)
            p1Denom += sum(trainMatrix[i])
            #print(p1Denom)
        else:
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])

    p1Vect = log(p1Num/p1Denom)
    p0Vect = log(p0Num/p0Denom)
    return p0Vect,p1Vect,pAbusive

def classifyNB(vecOClassify,p0Vec,p1Vec,p1Class):
    p1 = sum(vecOClassify*p1Vec) + log(p1Class)
    p0 = sum(vecOClassify*p0Vec) + log(1 - p1Class)
    if p1 > p0:
        return 1
    else: return 0

#进行测试
def jokeTest():
    stop_word = loadword(‘stopword1.txt‘)
    docList = [];classList = []
    for i in range(1,26):
        text = (‘joke/adult/%d.txt‘ % i)
        wordList = loadword(text)
        wordList = textParse(wordList,stop_word)
        docList.append(wordList)
        classList.append(1)

        text = (‘joke/normal/%d.txt‘ % i)
        wordList = loadword(text)
        wordList = textParse(wordList,stop_word)
        docList.append(wordList)
        classList.append(0)
    vocabList = createVocabList(docList)
    # 40个训练集,10个测试集
    trainingSet = list(range(50));testSet = []
    for i in range(10):
        randIndex = int(random.uniform(0, len(trainingSet)))
        testSet.append(trainingSet[randIndex]) #保证随机性,不管重复
        del(trainingSet[randIndex])
    trainMax = []; trainClasses = []
    for docIndex in trainingSet:
        #print(docIndex)
        trainMax.append(bagOfWordsVec(vocabList, docList[docIndex]))
        trainClasses.append(classList[docIndex])
    p0V,p1V,pSpam = trainNB0(array(trainMax),array(trainClasses))
    errorCount = 0
    for docIndex in testSet:
        wordVector = bagOfWordsVec(vocabList, docList[docIndex])
        if classifyNB(array(wordVector), p0V, p1V, pSpam) != classList[docIndex]:
            errorCount += 1
        print("the text %s \n the result %s the true result %s " % (docList[docIndex],classifyNB(array(wordVector), p0V, p1V, pSpam),classList[docIndex]))
    print("error rate: %f " % (float(errorCount)/len(testSet)))
# def main():
#     stop_word = []
#     stop_word = loadword(‘stopword.txt‘)
#     for item in stop_word:
#         print(item)
#main()
jokeTest()

    50个样例采用交叉验证的方法,40个训练,10个测试,错误率在10%左右。

     

    7.通过qq邮箱发送邮件

     参考:https://www.cnblogs.com/xshan/p/7954317.html

     

import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

my_sender=‘[email protected]‘    # 发件人邮箱账号
my_pass = ‘xxxxxxxxx‘              # 发件人邮箱密码(当时申请smtp给的口令)
my_user=‘[email protected]‘      # 收件人邮箱账号
def mail():
    ret=True
    try:
        content = "I love you!"
        msg=MIMEText(content,‘plain‘,‘utf-8‘)
        msg[‘From‘]=formataddr(["发件人昵称",my_sender])  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
        msg[‘To‘]=formataddr(["收件人昵称",my_user])              # 括号里的对应收件人邮箱昵称、收件人邮箱账号
        msg[‘Subject‘]="邮件主题-测试"                # 邮件的主题,也可以说是标题
        server=smtplib.SMTP_SSL("smtp.qq.com", 465)  # 发件人邮箱中的SMTP服务器,端口是465
        server.login(my_sender, my_pass)  # 括号中对应的是发件人邮箱账号、邮箱密码
        server.sendmail(my_sender,[my_user,],msg.as_string())  # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
        server.quit()# 关闭连接
    except Exception:# 如果 try 中的语句没有执行,则会执行下面的 ret=False
        ret=False
    return ret

ret=mail()
if ret:
    print("邮件发送成功")
else:
    print("邮件发送失败")

     8.整合

      所有代码稍后给个github上的链接:

      以下是正常笑话:

    以下是成人笑话:

原文地址:https://www.cnblogs.com/littlepear/p/8440939.html

时间: 2024-08-30 05:08:41

朴素贝叶斯趣味挑战项目的相关文章

趣味案例理解朴素贝叶斯

机器学习(10)之趣味案例理解朴素贝叶斯 转载:https://mp.weixin.qq.com/s/s0v_afLVqtJhZyn3qHlseQ 01 病人分类的例子 让我从一个例子开始讲起,你会看到贝叶斯分类器很好懂,一点都不难.某个医院早上收了六个门诊病人,如下表. 症状 职业 疾病 打喷嚏 护士 感冒 打喷嚏 农夫 过敏 头疼 建筑工人 脑震荡 头疼 建筑工人 感冒 打喷嚏 教师 感冒 头疼 教师 脑震荡 现在又来了第七个病人,是一个打喷嚏的建筑工人.请问他患上感冒的概率有多大? 根据贝

朴素贝叶斯项目实战

--判断一个患者的肿瘤是好是坏? 1.对数据集(威斯康星乳腺肿瘤数据集)分析 ############################# 朴素贝叶斯实战--判断肿瘤是良性的还是恶性的 ####################################### #导入数据集拆分工具 from sklearn.model_selection import train_test_split #导入威斯康星乳腺肿瘤数据集 from sklearn.datasets import load_breas

NLP系列(4)_朴素贝叶斯实战与进阶(转)

http://blog.csdn.net/han_xiaoyang/article/details/50629608 作者: 寒小阳 && 龙心尘 时间:2016年2月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/50629608 http://blog.csdn.net/longxinchen_ml/article/details/50629613 声明:版权所有,转载请联系作者并注明出处 1.引言 前两篇博文介绍了朴素贝叶

朴素贝叶斯(NB)复习总结

摘要: 1.算法概述 2.算法推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 内容: 1.算法概述 贝叶斯分类算法是统计学的一种分类方法,其分类原理就是利用贝叶斯公式根据某对象的先验概率计算出其后验概率,然后选择具有最大后验概率的类作为该对象所属的类. 之所以称之为"朴素",是因为贝叶斯分类只做最原始.最简单的假设: 1,所有的特征之间是统计独立的; 2,所有的特征地位相同.那么假设某样本x有a1,...,aM个属性 那么有:P(x)=P(a1,...,aM) = P(a

数据挖掘|朴素贝叶斯算法

作者:张一 链接:https://zhuanlan.zhihu.com/p/21571692 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 因为后期的项目将涉及到各种各样的价格数据处理问题,所以我们现在开始学习一些简单的数据清洗与算法的知识.关于算法,以前听起来觉得好高大上,现在开始学,觉得书上的描述并不是很通俗易懂,所以用自己的语言来简要写一下这些算法~ 注:非商业转载注明作者即可,商业转载请联系作者授权并支付稿费.本人已授权"维权骑士"网站(ht

NLP系列(3)_用朴素贝叶斯进行文本分类(下)

作者: 龙心尘 && 寒小阳 时间:2016年2月. 出处: http://blog.csdn.net/longxinchen_ml/article/details/50629110 http://blog.csdn.net/han_xiaoyang/article/details/50629587 声明:版权所有,转载请联系作者并注明出处 1. 引言 上一篇文章我们主要从理论上梳理了朴素贝叶斯方法进行文本分类的基本思路.这篇文章我们主要从实践上探讨一些应用过程中的tricks,并进一步分

NLP系列(4)_朴素贝叶斯实战与进阶

作者: 寒小阳 && 龙心尘 时间:2016年2月. 出处: http://blog.csdn.net/han_xiaoyang/article/details/50629608 http://blog.csdn.net/longxinchen_ml/article/details/50629613 声明:版权所有,转载请联系作者并注明出处 1.引言 前两篇博文介绍了朴素贝叶斯这个名字读着"萌蠢"但实际上简单直接高效的方法,我们也介绍了一下贝叶斯方法的一些细节.按照老规

基于朴素贝叶斯的花生品种识别

最近一段时间,正在学习机器学习与模式识别,为了验证算法,仍然用了之前做过的项目的一些图片作为数据采集的样本,进行数据采集.前段时间,做了一个花生籽粒的识别程序,是基于SVM+HOG的,这次则是采用朴素贝叶斯来进行识别.采集了20个品种,每个品种50个样本,共1K个数据. 朴素贝叶斯分类器(Naive Bayes Classifier,或 NBC)发源于古典数学理论,有着坚实的数学基础,以及稳定的分类效率.同时,NBC模型所需估计的参数很少,对缺失数据不太敏感,算法也比较简单.理论上,NBC模型与

Step by Step 改进朴素贝叶斯算法

引言 如果你对naive bayes认识还处于初级阶段,只了解基本的原理和假设,还没有实现过产品级的代码,那么这篇文章能够帮助你一步步对原始的朴素贝叶斯算法进行改进.在这个过程中你将会看到朴素贝叶斯假设的一些不合理处以及局限性,从而了解为什么这些假设在简化你的算法的同时,使最终分类结果变得糟糕,并针对这些问题提出了改进的方法. 朴素贝叶斯(Naive Bayes) 出处: <机器学习>(Machine Learning by Tom M.Mitchell) 符号和术语 假设待分类的实例 X 可