接单---毕设之豆瓣电影分析可视化系统基于tkinter界面requests爬虫实现

简 介: 此系统主要通过爬取豆瓣电影TOP250及其用户短评,并通过Tkinter设计用户操作界面,将数据分析的结果进行展示。

关键词: python, tikinter,gui,requests,爬虫,桌面程序
————————————————

第一次写,先上一张成品图 :

 


 1、爬虫之豆瓣TOP250


爬取网页:

def getData(baseurl):
    
    datalist = []
    for i in range(0, 10):
        url = baseurl + str(i * 25)
        html = askURL(url)  # 保存爬取的网页源码

        # 逐一解析数据
        soup = BeautifulSoup(html, "html.parser")

        for item in soup.find_all('div', class_="item"):
            # print(item)  # 测试
            data = []  # 保存
            item = str(item)

            # re库正则表达式来查找指定字符串,形成列表
            Link = re.findall(findLink, item)[0]  # 链接
            # print(Link)
            data.append(Link)

            ImaSrc = re.findall(findImaSrc, item)[0]  # 图片链接
            # print(ImaSrc)
            data.append(ImaSrc)

            Title = re.findall(findTitle, item)[0]  # 片名:可能只有一个中文名,没有外译名字
            if (len(Title) == 2):
               
                cTitle = Title[0]  # 添加中文名
                # print(cTitle)
                data.append(Title)
                oTitle = Title[1].replace("/", "")  # 外译片名
             
            else:
                data.append(Title)
              

            Rating = re.findall(findRating, item)[0]  # 评分
            data.append(Rating)

            Judge = re.findall(findJudge, item)[0]  # 评价人数
            data.append(Judge)

            Inq = re.findall(findInq, item)  # 概述
            if len(Inq) != 0:
                Inq = Inq[0].replace("。", "")  # 去掉句号
                data.append(Inq)
            else:
                data.append(" ")  # 留空

            Bd = re.findall(findBd, item)[0]  # 相关内容

            temp = re.search('[0-9]+.*\/?', Bd).group().split('/')
            year, country, category = temp[0], temp[1], temp[2]  # 得到年份、地区、类型

            data.append(year)
            data.append(country)
            data.append(category)
            datalist.append(data)  # 把处理好的一部电影信息放入datalist

    return datalist

保存数据:

# 保存数据
def saveData(datalist, savepath):
    text.insert(END, "开始保存!!!! \n")
    text.update()
    book = xlwt.Workbook(encoding="utf-8")  # 创建workbook对象
    sheet = book.add_sheet('豆瓣电影Top250', cell_overwrite_ok=True)  # 创建工作表

    # 制作表头
    col = ("电影详情链接", "图片链接", "中文名",  "评分", "评价数", "概述", "上映年份","制片国家","类型")
    for i in range(0, len(col)):
        sheet.write(0, i, col[i])

    for i in range(0, 250):
        # print("第%d条"%(i+1))
        data = datalist[i]
        for j in range(0, len(col)):
            sheet.write(i + 1, j, data[j])

这些是针对豆瓣电影TOP250,即https://movie.douban.com/top250,这个链接页面进行爬取相应字段。


 2、爬虫之豆瓣影评

def start_spider(urls,name):
    
    base_url = urls+'comments'
    print(base_url)  #打印  url
    start_url = base_url + '?start=0'  #给url 一个初始的链接
    number = 1
    html = request_get(start_url)
    marvelthree = []  
    while html.status_code == 200:   
        selector = etree.HTML(html.text)
        nextpage = selector.xpath("//div[@id='paginator']/a[@class='next']/@href")
        nextpage = nextpage[0] 
        next_url = base_url + nextpage 
        # 获取评论
        comments = selector.xpath("//div[@class='comment']")
        #遍历获取的结果
        for each in comments:
            marvelthree.append(get_comments(each)) 
        data = pd.DataFrame(marvelthree)
 
        try:
       
            if number == 1:
                csv_headers = ['用户', '是否看过', '五星评分', '评论时间', ]
                f_name='./电影数据/'+name +".xlsx"  #路径
                #表头存入到表格中
                data.to_excel(f_name, header=csv_headers, index=False, encoding='utf-8')

            else:
                #将数据存入表格
                data.to_excel(f_name, header=False, index=False, encoding='utf-8')
        except UnicodeEncodeError:
            print("编码错误, 该数据无法写到文件中, 直接忽略该数据")
        html = request_get(next_url)

def request_get(url):
    '''
    使用 Session 能够跨请求保持某些参数。
    它也会在同一个 Session 实例发出的所有请求之间保持 cookie
    '''
    #设置延时3秒
    timeout = 3
 
    UserAgent_List = [
        "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2226.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.4; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2225.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2225.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2224.3 Safari/537.36",
        "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36",
        "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 4.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.2309.372 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.2117.157 Safari/537.36",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1866.237 Safari/537.36",
    ]
    #请求头的header
    header = {
        'User-agent': random.choice(UserAgent_List),
        'Host': 'movie.douban.com',

    }
  
    session = requests.Session()

    cookie = {  #用自己的
        }
 
    time.sleep(random.randint(2, 10))
    #请求后的页面
    response = requests.get(url, headers=header, cookies=cookie, timeout = 3)
    if response.status_code != 200: 
        print(response.status_code)  
    return response  #返回结果页面html

def get_comments(eachComment):
    commentlist = []

    user = eachComment.xpath("./h3/span[@class='comment-info']/a/text()")[0]  # 用户
    watched = eachComment.xpath("./h3/span[@class='comment-info']/span[1]/text()")[0]  # 是否看过
    rating = eachComment.xpath("./h3/span[@class='comment-info']/span[2]/@title")  # 五星评分
   
    if len(rating) > 0:
        #有的话就拿第一个
        rating = rating[0]
    comment_time = eachComment.xpath("./h3/span[@class='comment-info']/span[3]/@title")  # 评论时间
    if len(comment_time) > 0:
        # 有的话就拿第一个
        comment_time = comment_time[0]
    else:
        # 有些评论是没有五星评分, 需赋空值
        #如果没有评分  那rating  就是时间,将时间给comment_time
        comment_time = rating
        #置空
        rating = ''


    commentlist.append(user)
    commentlist.append(watched)
    commentlist.append(rating)
    commentlist.append(comment_time)
    return commentlist

普通爬虫就不做过多解释了。 


 3、可视化

#做个开始爬的方法
def starPinglu():
    #给前端打印  评论爬虫开始
    text.insert(END, "评论爬虫开始!!!! \n")
    text.update() #更新上去
    df = pd.read_excel('./豆瓣电影Top 250.xls') #读取   豆瓣电影Top 250.xls
    d_l=df['电影详情链接'].head(10).to_list() #取电影详情链接 这列的前十个 并转换成列表

    numb=0
    #遍历前十电影链接
    for i in d_l:
        #获取对应电影名
        name=qianshi(numb)
        #开始爬虫 传进去电影链接  电影名
        start_spider(i,name)
        numb+=1 

做了一个开始爬的方法   后面会有按钮调用 


 

#可视化图表
def pingfen():
    df=pd.read_excel('./豆瓣电影Top 250.xls')
    d_p=df.groupby("评分").count()
    a.clear()
    a.plot(d_p)
    canvas_spice.draw()
def shangyingnianfen():
    df=pd.read_excel('./豆瓣电影Top 250.xls')
    df['年'] = df["上映年份"].str[0:4]
    a.clear()
    d_p=df.groupby("年").count()
    a.plot(d_p)
    canvas_spice.draw()

 评论分布,上映年份的点线图    这里换成柱状图也行的或其他图形


 4、tkinter做的界面

def ui():
    global text
    label = Label(root, text="事件输出框-----文本显示", bg="yellow")
    text = Text(root, width=35, height=5,bg="Cyan")
    # 第四行开始按扭,command绑定事件
    b_Start_250 = Button(root, text='开始爬豆瓣T250', bg="pink",command=lambda: thread_it(func))
    b_Start_shufen=Button(root, text='评分分布图',bg="pink", command=lambda: thread_it(pingfen))
    b_Start_shangying = Button(root, text='上映年份', bg="pink", command=lambda: thread_it(shangyingnianfen))

    #单个电影的 自己做方法就可以  然后依次添加进来 


    label2.place(x=350, y=15)
    b_Start_pinglu.place(x=550,y=13)
    #布局标题
    label.place(x=10, y=50)
    #布局文本框
    text.place(x=10, y=80)
    b_Start_250.place(x=10, y=10)
    b_Start_shufen.place(x=130, y=10)
    b_Start_shangying.place(x=220, y=10)


    fig = plt.figure(figsize=(13, 17), dpi=50)  # 图像比例
    global a
    a = fig.add_subplot(211)  # 划分区域
    global canvas_spice
    canvas_spice = FigureCanvasTkAgg(fig, root)
    canvas_spice.get_tk_widget().place(x=0, y=120)  # 放置位置

 很多人在做Tkinter的时候,启动一个耗时较长的方法后,界面就卡死了。这是因为整个程序是单线程的。所以,需要开多线程。如下:

def thread_it(func, *args):
    '''将函数打包进线程'''
    # 创建
    t = threading.Thread(target=func, args=args)
    # 守护 !!!
    t.setDaemon(True)
    # 启动
    t.start()

这种方法我是屡试不爽,很有用也很方便。 


最后一张展示图: 

 


另:本工作室长期接单,放单。涉及领域有python java 前后端 机器学习 网站 系统 app 小程序等。

需要接单加v备注技术领域:ad2021wyz

需要做单加v备注需要做什么:ad2020wyz

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值