zoukankan      html  css  js  c++  java
  • python写的百度贴吧邮箱采集(带界面)

    之前有个网友在贴吧做营销,那个贴吧每天都会产生100多的邮箱号,有网友就让我写个软件,别人发帖让用户留邮箱,自己却用脚本把用户留的邮箱全部采集下来,软件已经经历了两个版本,有时间再改进一下。

    软件界面:

    下面代码是程序主入口,主要写了软件界面和函数调用,界面是tkinter写的,因为我觉得这个比较简单当时就学这个了,就是界面比较丑,一些比较简单的软件足够用了,代码比较乱,之前一直用面向过程写方法函数,现在慢慢改习惯用面向对象了,软件的每调用一些耗时的函数,必须用上
    threading创建线程,开创新的线程就不会影响软件界面,不然软件会卡死。
    from tieba_pc import *
    # from tkinter import W,E,N,S,Button,Label,Text,Tk,Entry
    from tkinter import INSERT
    import tkinter.messagebox
    from threading import Thread
    # from requests import get
    from tkinter import *
    import webbrowser
    #import threading
    
    def qk():  # 清空按钮
        text1.delete(1.0, END)
        text2.delete(1.0, END)
    
    def tieba_cj():
        #  读输入的域名
        text_content = (text1.get("0.0", "end").replace(" ", "")).split("
    ")
        text_content.pop()  # 列表最后一个元素是空删除它
    
        if text_content[0] == '':
            tkinter.messagebox.showinfo(title='提示', message='麻烦把贴吧名填一下再提交!')
        else:
            rad = r.get()  # 控制采集时间段
            pn = e.get()     # 贴吧翻页
            yx = tm.get()      # 运行状态控制
            xcx = xc.get()      # 下次控制
            bcwj = wj.get()
    
            x=0     # 控制贴吧数
            text2.insert(END, "可以最小化软件去忙其他事了!" + '
    ')
            for ming in text_content:     # 这里对输入的贴吧循环采集
                # 单线程
                if xcx == 1 :
                    tieba_caiji(ming, int(rad), text2, int(pn), int(yx),int(bcwj))
                # 多线程
                elif xcx == 2 :
                    t = Thread(target=tieba_caiji, args=(ming, int(rad), text2, int(pn), int(yx),int(bcwj),))
                    t.start()
                    t.join()
    
                x = x + 1
                if x == 5 :
                    break
                time.sleep(3)
            # 全部采集完成
    
    
    # 版本更新函数
    def bbgx():
    
        pass
    
    # 采集函数
    def th1():
        t1 = Thread(target=tieba_cj)
        t1.start()
    # 版本更新函数
    def th2():
        t1 = Thread(target=bbgx)
        t1.start()
    # 说明提示
    def sm():
    
        tkinter.messagebox.showinfo(title='说明', message='欢迎使用本软件,软件仅用于交流使用!
    软件用于贴吧邮箱采集,可以选择多个贴吧监控邮箱回复采集,可以选择回复时间进行采集,可以24小时不间断采集,多线程采集,采集的邮箱保存到文本文件,可以轻松复制邮件群发!')
    
    ###########------公共变量定义------------#########
    
    banben = 1.1
    
    ###########-----------------   UI 界面乱写开始           -------------------------#########
    
    root=Tk() #生成root主窗口
    root.title('贴吧邮箱采集器')
    root.resizable(0,0)
    root.geometry('840x680')
    
    # 两个布局控件
    frm1 = tkinter.Frame(root,height=100,width=400,).grid(row=0,column=0,sticky=N+W)
    frm2 = tkinter.Frame(root,height=280,width=200,).grid(row=7,column=0,padx=15,sticky=N+W)
    frm3 = tkinter.Frame(root,height=280,width=260,).grid(row=7,column=1,padx=15,sticky=N+W) # background='#FFFFFF'height=380,width=260,
    
    
    # 按钮控件
    Button(frm1,text='开始采集',height=2,width=20,fg='red',font=10,command=th1).grid(row=0,column=0,columnspan=1,pady=0,padx=15,)
    Button(frm1,text='清空',height=0,width=8,fg='red',font=10,command=qk).grid(row=0,column=1,pady=0,columnspan=1,padx=10,sticky=E)
    Button(frm1,text='说明',height=0,width=8,fg='red',font=10,command=sm).grid(row=0,column=2,pady=0,padx=10,sticky=E)
    
    
    # 单选标签
    r=tkinter.IntVar()#给单选框添加variable,用于显示value值
    r.set(1)
    radio1=tkinter.Radiobutton(frm1,text="采集当天",value=1,variable=r).grid(row=1,column=0,pady=10)
    radio2=tkinter.Radiobutton(frm1,text="不限制时间",value=10,variable=r).grid(row=1,column=1,pady=10)
    radio3=tkinter.Radiobutton(frm1,text="采集前七天",value=7,variable=r).grid(row=1,columnspan=2,pady=10)
    
    Label(frm1, text="运行状态:", height=0,).grid(row=2, column=0,columnspan=1,sticky=W+E+N+S)  # columnspan=2,
    # 单选标签
    tm=tkinter.IntVar()#给单选框添加variable,用于显示value值
    tm.set(1)
    tmadio1=tkinter.Radiobutton(frm1,text="运行一次",value=1,variable=tm).grid(row=2,column=1,pady=10)
    tmadio2=tkinter.Radiobutton(frm1,text="每隔1小时运行一次",value=2,variable=tm).grid(row=2,columnspan=2,pady=10)
    
    
    Label(frm1, text="线程选择:", height=0,).grid(row=3, column=0,columnspan=1,sticky=W+E+N+S)  # columnspan=2,
    # 单选标签
    xc=tkinter.IntVar()#给单选框添加variable,用于显示value值
    xc.set(1)
    xcadio1=tkinter.Radiobutton(frm1,text="单线程采集",value=1,variable=xc).grid(row=3,column=1,pady=10)
    xcadio2=tkinter.Radiobutton(frm1,text="多线程采集",value=2,variable=xc).grid(row=3,columnspan=2,pady=10)
    
    
    # 文本加文本框
    Label(frm1, text="采集贴吧前多少页(最好10以内):", height=0,).grid(row=4, column=0,columnspan=1,sticky=W+E+N+S)
    e = StringVar()
    Entry(frm1, bd =0,textvariable=e).grid(row=4,column=1,pady=10)
    e.set('1')
    
    
    Label(frm1, text="是否存入数据文件:", height=0,).grid(row=5, column=0,columnspan=1,sticky=W+E+N+S)  # columnspan=2,
    # 单选标签
    wj=tkinter.IntVar()#给单选框添加variable,用于显示value值
    wj.set(1)
    wjadio1=tkinter.Radiobutton(frm1,text="",value=1,variable=wj).grid(row=5,column=1,pady=10)
    wjadio2=tkinter.Radiobutton(frm1,text="",value=2,variable=wj).grid(row=5,columnspan=2,pady=10)
    
    
    
    # 文本标签
    Label(frm1, text="输入贴吧名不要带吧、一行一个贴吧,一次最多采集5个", height=0,).grid(row=6, column=0,sticky=W+E+N+S,padx=25,pady=1) # ,columnspan=1
    Label(frm1, text="运行日志输出区", height=0,).grid(row=6, column=1,columnspan=2,sticky=W+E+N+S,pady=1)
    
    # 多行输入框
    text1 = Text(frm2,width=25,height=14,font=10)
    text2 = Text(frm3,width=32,height=14,font=10)
    
    
    # 布局输入框,这里单独拿出来放,不然出问题
    text1.grid(row=7,column=0,padx=5,pady=1)
    text2.grid(row=7,column=1,padx=5,pady=1)
    
    Label(frm1, text="版本:%s - 大铭    "%banben, height=0,).grid(row=8, column=2)
    
    # 检查更新函数
    th2()
    root.mainloop()             #进入消息循环(必需组件)
    View Code

    爬虫函数,被软件界面调用的函数,包括爬取和将数据写入文件。

    from main_def import *
    import requests,re
    import datetime,time
    from tkinter import END
    
    headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36"}
    
    # 单个帖子爬虫
    def tz_cj(url,time_xz):
        #########-----------分割线--------------#############################
        #########------------开始帖子邮箱采集-------------####################
    
        # 选择采集时间控制变量,1 为当天,7 为前七天,10 为不限制时间
        #time_xz = 7
        # 获取当前时间
        time1 = datetime.datetime.now().strftime('%Y-%m-%d')
        # 邮箱存储列表
        yx_list = []
        # 循环控制变量
        pn = 1
        while True:
            t_url = url + "?pn=" + str(pn)
            t_re_html = requests.get(t_url, headers=headers).text
    
            # 获取页数
            red = re.findall('<span class="red">(.*?)</span>', t_re_html)[0]
    
            # 正则匹配提取每一个楼层
            t_nr_1 = re.findall('<div class="l_post j_l_post l_post_bright  "(.*?)</div><br>', t_re_html, re.S)
            t_nr_2 = re.findall('<div class="d_post_content_main ">(.*?)</span></div><ul class="p_props_tail props_appraise_wrap"></ul>', t_re_html, re.S)
            t_nr = t_nr_1 + t_nr_2
            # 循环遍历页面所有楼层
            for re_lc in t_nr:
                # 这里做一个错误跳转,楼层没有邮箱则跳过
                try:
                    # 提取楼层发布时间
                    times = re.search(r"(d{4}-d{1,2}-d{1,2})", re_lc)
                    tims = (times.group(0))
    
                    # 提取楼层邮箱
                    pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,5}'
                    items = re.findall(pattern, re_lc)[0]
                    # 判断采集当天
                    if time_xz == 1:
                        # 只爬取当天邮箱
                        if time1 == tims:
                            yx_list.append(items)
                    # 判断采集前七天
                    elif time_xz == 7:
                        time7 = datetime.datetime.today().date() - datetime.timedelta(days=8)
                        if str(tims) > str(time7):
                            yx_list.append(items)
                    # 判断采集不限制时间
                    elif time_xz == 10:
                        yx_list.append(items)
    
                except:
                    continue
    
            # 加页数
            pn = pn + 1
            # 判断翻页完成跳出循环
            if pn - 1 == int(red):
                break
    
            time.sleep(0.5)
    
        return yx_list    # 返回采集到的邮箱
    
    # 文件写入函数
    def text_save(filename,data,ts,text2): #filename为写入文件的路径,data为要写入数据列表.
        datas = list(set(data))    # 去除重复邮箱
        times = datetime.datetime.now().strftime('%Y-%m-%d-%H')
        file = open(times + "-" + filename + "吧邮箱采集文件.txt", 'a')
        for i in range(len(datas)):
            s = str(datas[i]).replace('[', '').replace(']', '')  # 去除[],这两行按数据不同,可以选择
            s = s.replace("'", '').replace(',', '') + '
    '  # 去除单引号,逗号,每行末尾追加换行符
            file.write(s)
        file.close()
    
        text2.insert(END, "第%d个帖邮箱采集成功保存文件!"%ts + '
    ')
    
        wjm = times + "-" + filename + "吧邮箱采集文件.txt"
        return wjm     # 把文件名返回
    
    
    # 页面入口函数
    def tieba_caiji(kw,time_xz,text2,pn,yx,bcwj):   # kw传贴吧名,time_xz采集控制当天  text2传一个句柄 ,yx传运行状态  pn 传贴吧翻页
    
        while True:
            for ye in range(int(pn)):  # 这个循环是循环贴吧翻页
                pn = ye * 50
                url = "https://tieba.baidu.com/f?kw=%s&ie=utf-8&pn=%d" % (kw, pn)
                # 爬贴吧第一页的所有帖子
                html = requests.get(url, headers=headers).text
                re_html = re.findall('<div class="threadlist_title pull_left j_th_tit ">(.*?)</div>', html, re.S)
    
                ts = 1  # 统计帖数
                for i in re_html:
                    href = re.findall('href="(.*?)"', i, re.S)[0]
                    t_url = "https://tieba.baidu.com" + href
                    yx_list = tz_cj(t_url, time_xz)
                    wjm = text_save(kw, yx_list, ts, text2)
                    time.sleep(3)
                    ts = ts + 1
                text2.insert(END, "%s吧第%d页采集完成!" % (kw,ye+1) + '
    ')
            text2.insert(END, "%s吧采集完成!" % (kw) + '
    ')
    
            # 保存入今日文件
            if bcwj == 2 :
                wenjian_xr(wjm)
    
            #如果为 2 则等待1小时 运行
            if yx == 2 :
                time.sleep(3600)
            # 翻页完成,退出软件
            else:
                break
    View Code

    这个函数有点啰嗦了,将每次采集的数据写入一个总TXT文件。

    import datetime
    import os
    
    
    # 将当前采集到的文件写入今日文件
    def wenjian_xr(times):    # 传入当前采集到的文件名
        time3 = datetime.datetime.now().strftime('%Y-%m-%d')
    
        # 判断是否存在数据目录,没有则创建
        wenjian = os.path.exists('./dmzy5')
        if wenjian == False:
            os.mkdir('dmzy5')
            #print("创建成功")
    
        file = open(times)
        lines = file.readlines()
        list2 = ([' '.join([i.strip() for i in price.strip().split('	')]) for price in lines])
        # 读取传入的文件,变成列表完成
        file.close()
    
        # 将采集到的文件写入今日数据文件
        file_2 = open("./dmzy5/" + time3 + "- 邮箱采集文件.txt", 'a')
        for i in range(len(list2)):
            s = str(list2[i]).replace('[', '').replace(']', '')  # 去除[],这两行按数据不同,可以选择
            s = s.replace("'", '').replace(',', '') + '
    '  # 去除单引号,逗号,每行末尾追加换行符
            file_2.write(s)
        file_2.close()
    
        # 读取今日数据文件,变成列表
        file_3 = open("./dmzy5/" + time3 + "- 邮箱采集文件.txt")
        lines2 = file_3.readlines()
        lines2 = ([' '.join([i.strip() for i in price.strip().split('	')]) for price in lines2])
        file_3.close()
        # 今日数据文件去重
        lists = []  # 最后写入的列表
        for i in lines2:
            if i not in lists:
                lists.append(i)
    
        # 把原文件删除,重新创建写入
        os.remove("./dmzy5/" + time3 + "- 邮箱采集文件.txt")
        file_4 = open("./dmzy5/" + time3 + "- 邮箱采集文件.txt", 'a')
        for i in range(len(lists)):
            s = str(lists[i]).replace('[', '').replace(']', '')  # 去除[],这两行按数据不同,可以选择
            s = s.replace("'", '').replace(',', '') + '
    '  # 去除单引号,逗号,每行末尾追加换行符
            file_4.write(s)
        file_4.close()
    View Code
  • 相关阅读:
    springmvc源码分析上之HandlerMapping
    java web api接口调用
    centos6 hadoop2.7.3分布式搭建
    大话java基础知识一之为什么java的主函数入口必须是public static void
    jQuery引用
    windows 服务的卸载
    java 环境安装
    python matplotlib 折线图的制作
    python matplotlib 简单柱状图的制作
    python 安装库时 Failed building wheel for 错误处理
  • 原文地址:https://www.cnblogs.com/hongming/p/12901657.html
Copyright © 2011-2022 走看看