数据采集——豆瓣电影 《肖申克的救赎》影评数据

一、目的与要求

1、目的

通过实验,掌握爬虫的基本原理和相关知识,并能够运用所学知识进行网页数据的获取和解析。理解爬虫的网页分类:通过实验,了解并能够区分静态网页和动态网页,掌握爬取静态网页和动态网页的方法和技巧。爬取和解析网页的流程:通过实验,掌握爬虫的基本流程,包括发送请求、获取网页源代码、解析网页数据等步骤,能够熟练运用urllib库或requests库获取网页源代码。通过实验掌握Xpath语法使用规则,能够提取网页中的目标数据。数据解析与可视化:掌握使用re、lxml等工具进行数据解析,实现数据的清洗和提取。同时,学会使用wordcloud库和matplotlib库进行数据可视化,以更直观、直观地展示爬取的数据。运用数据处理工具:通过实验,掌握jieba、numpy和pandas等数据处理工具的基本使用方法,能够对爬取的数据进行分词、统计、分析等操作,进一步挖掘数据的价值。

通过完成以上实验目的,将掌握爬虫的基本原理和技术,能够独立进行网页数据的获取和解析,并能够运用数据处理工具进行数据分析和可视化,进一步提高信息处理和应用能力。

  1. 要求

实现爬取电影信息,和影评信息的需求以及爬取需要重复跳转页面获取城市信息的需求

具体要求: 

1)爬取字段:电影名、导演、主演、类型、制片国家/地区、语言、上映日期、片长、 综合评分、评价人数;影评用户名、用户评分、评论发布时间、评论正文、有用数量、回应 数量等等。

2)使用工具:Pythonurllibrequestslxmlseleniumscrapypandastime 等适当选择搭配使用。

3)解析方式:正则表达式、Xpathbs4 等。

二、课程设计内容

1、题目和环境

题目:豆瓣电影 Top250《肖申克的救赎》电影影评数据的爬取

语言:Python

环境:Anaconda3+Pycharm或Jupyter Notebook

2、过程与步骤

实现该豆瓣电影 Top250《肖申克的救赎》电影影评数据的爬取所涉及的文件:

  1. publish_city.csv:用于存储爬虫处理后的数据。

(2)filmreview3.csv:用于存储爬虫处理后的电影影评数据。

(3)豆瓣电影 Top250《肖申克的救赎》电影影评数据的爬取.py:用于数据处理。

(4)豆瓣分析电影 Top250《肖申克的救赎》电影影评数据的爬取.py:用于数据分析。

操作过程与步骤如下:

2.1.爬取数据

(1)该段代码使用了pandas库和selenium库来爬取豆瓣电影的页面数据。首先,其中使用了pandas库来导入了pandas模块。接着,使用了selenium库的webdriver模块来启动Chrome浏览器,并通过browser.get()打开了指定网页。然后,使用了time库的sleep函数来等待2秒,以确保页面加载完全。接下来,使用了selenium库的webdriver模块中的page_source属性获取当前页面的源代码,并将其赋值给变量text。最后,使用了lxml库的etree模块中的HTML方法将text转化成可解析的HTML树,并将其赋值给变量tree。

核心代码如图1所示:

import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
from lxml import  etree
browser=webdriver.Chrome()
browser.get('https://movie.douban.com/subject/1292052/')
sleep(2)
text=browser.page_source
tree=etree.HTML(text)

图1 爬取豆瓣网站数据

2使用xpath语句获取肖申克救赎的电影信息。复制网页xpath语句添加text()输出文字,然后使用print输出爬取到的内容。

核心代码如下所示:

# 电影名
movie_name=tree.xpath('//*[@id="content"]/h1/span[1]/text()')
sleep(2)
 # 导演
movie_Director=tree.xpath('//*[@id="info"]/span[2]/span[2]/a/text()')
sleep(2)
 # 主演
movie_Starring=tree.xpath('//*[@id="info"]/span[3]/span[2]/span/a/text()')
sleep(2)
 # 类型
movie_type1=tree.xpath('//*[@id="info"]/span[5]/text()')
movie_type2=tree.xpath('//*[@id="info"]/span[6]/text()')
sleep(2)
#制片国家/地区
movie_country=tree.xpath('//*[@id="info"]/span[7]/following-sibling::text()[1]')
sleep(2)
# #语言
movie_language=tree.xpath('//*[@id="info"]/span[8]/following-sibling::text()[1]')
sleep(2)
# #上映日期
movie_date1=tree.xpath('//*[@id="info"]/span[10]/text()')
movie_date2=tree.xpath('//*[@id="info"]/span[11]/text()')
sleep(2)
#片长
movie_time=tree.xpath('//*[@id="info"]/span[13]/text()')
sleep(2)
#综合评分
overall_score=tree.xpath('//*[@id="interest_sectl"]/div[1]/div[2]/strong/text()')
sleep(2)
#评价人数
number_evaluators=tree.xpath('//*[@id="interest_sectl"]/div[1]/div[2]/div/div[2]/a/span/text()')
sleep(2)
print({'电影名':movie_name,'导演':movie_Director,'主演':movie_Starring,'类型1':movie_type1,
       '类型2':movie_type2,'制片国家/地区':movie_country,'语言':movie_language,
       '上映日期1':movie_date1,'上映日期2':movie_date2,'片长':movie_time,'综合评分':overall_score,
       '评价人数':number_evaluators})

2 爬取肖申克救赎电影信息

运行结果如图4所示:

图3爬取肖申克救赎电影信息结果

3首先,它通过点击找到页面上的评论按钮并点击,然后等待3秒钟。接下来,创建了一个名为 filmreview_info的空DataFrame,用于存储爬取到的评论信息。然后进入一个循环,循环50次。在每次循环中首先获取当前页面的HTML代码,并将其解析成一个树形结构。然后查找评论的相关元素,并提取出影评用户名、用户评分、评论发布时间、评论正文、有用数量和回应数量等信息,并将其存储到filmreview_info​中。如果该页是需要跳过的页面,则通过查找下一页按钮并点击进行跳过,并等待3秒钟。最后,它将filmreview_info​保存为CSV文件,并关闭浏览器。

核心代码下所示:

#点击影评全部按钮
browser.find_element(By.XPATH, '//*[@id="reviews-wrapper"]/header/h2/span/a').click()
sleep(3)
filmreview_info = pd.DataFrame(columns=['影评用户名', '用户评分', '评论发布时间', '评论正文', '有用数量', '回应数量'])
for j in range(50):
    text = browser.page_source
    tree = etree.HTML(text)
    sleep(3)
    a = tree.xpath('//*[@id="content"]/div/div[1]/div[1]/div')
    if j == 1 or j == 9 or j == 13 or j == 14 or j == 17 or j == 22 or j == 23 or j == 30 or j == 31 or j == 32 or j == 48 or j == 49:
        # 查找下一页按钮并点击
        next_page_button = browser.find_element(By.CLASS_NAME, 'next')
        next_page_button.click()
        sleep(3)
    else:
        for i in range(len(a)):
            # 影评用户名
            filmreview_name = tree.xpath('/html/body/div[3]/div[1]/div/div[1]/div[1]/div[' + str(i + 1) + ']/div/header/a[2]/text()')
            sleep(2)
            # 用户评分
            user_rating = tree.xpath(' /html/body/ div[3]/div[1] / div / div[1] / div[1] / div[' + str(i + 1) + '] / div / header / span[1]/@title')
            sleep(2)
            # 评论发布时间
            publish_time = tree.xpath('/html/body/div[3]/div[1]/div/div[1]/div[1]/div[' + str(i + 1) + ']/div/header/span[2]/text()')
            sleep(2)
            # 评论正文
            publish_content = tree.xpath('/html/body/div[3]/div[1]/div/div[1]/div[1]/div[' + str(i + 1) + ']/div/div/div[1]/div/text()[1]')
            sleep(2)
            # 有用数量
            useful_count = tree.xpath('/html/body/div[3]/div[1]/div/div[1]/div[1]/div[' + str(i + 1) + ']/div/div/div[3]/a[1]/span/text()')
            sleep(2)
            # 回应数量
            response_count = tree.xpath(
                '/html/body/div[3]/div[1]/div/div[1]/div[1]/div[' + str(i + 1) + ']/div/div/div[3]/a[3]/text()')
            sleep(2)
            new = pd.DataFrame(
                {'影评用户名': filmreview_name, '用户评分': user_rating, '评论发布时间': publish_time, '评论正文': publish_content,
                 '有用数量': useful_count, '回应数量': response_count})
            filmreview_info = filmreview_info.append(new, ignore_index=True)
            filmreview_info.to_csv('filmreview3.csv', index=False, encoding='utf-8')
        # 查找下一页按钮并点击
        next_page_button = browser.find_element(By.CLASS_NAME, 'next')
        next_page_button.click()
        sleep(3)
        a.pop()
browser.quit()

图4 爬取影评数据代码

运行结果如图8所示:

8  爬取影评数据结果

  1. 首先找到页面上的评论按钮并点击,然后等待3秒钟。接下来,创建了一个名为city_list_info的空DataFrame,用于存储爬取到的用户城市信息。然后进入一个循环,循环50次。在每次循环中首先获取当前页面的HTML代码,并将其解析成一个树形结构。然后,查找评论的相关元素,并逐个点击用户名名称,进入用户主页。再次获取用户主页的HTML代码,并将其解析成一个新的树形结构。然后提取出用户的城市信息,并将其存储到city_list_info中。接着将city_list_info​保存为CSV文件,并返回到上一个页面。最后,查找下一页按钮并点击进行翻页,并等待3秒钟。循环结束后,关闭浏览器。

核心代码如图9,图10所示:

# 点击影评全部按钮
browser.find_element(By.XPATH,'//*[@id="reviews-wrapper"]/header/h2/span/a').click()
sleep(3)
city_list_info = pd.DataFrame(columns=['用户城市'])
for j in range(50):
    text = browser.page_source
    tree = etree.HTML(text)
    sleep(3)
    a = tree.xpath('//*[@id="content"]/div/div[1]/div[1]/div')
    for i in range(len(a)):
        #点击用户名名称
        browser.find_element(By.XPATH,'/html/body/div[3]/div[1]/div/div[1]/div[1]/div['+str(i+1)+']/div/header/a[2]').click()
        sleep(2)
        #进入用户页面
        text=browser.page_source
        tree=etree.HTML(text)
        publish_city=tree.xpath('//*[@id="profile"]/div/div[2]/div[1]/div/a/text()')
        sleep(2)
        city_list = pd.DataFrame({'用户城市': publish_city})
        city_list_info = city_list_info.append(city_list, ignore_index=True)
        city_list_info.to_csv('publish_city.csv', index=False, encoding='utf-8')
        browser.back()
        sleep(3)
    # 查找下一页按钮并点击
    next_page_button = browser.find_element(By.CLASS_NAME, 'next')
    next_page_button.click()
    sleep(3)
    a.pop()
browser.quit()

9 爬取用户城市数据代码

运行结果如图11所示:

11 爬取用户城市数据结果

2.2.数据分析

  1. 该段代码的功能是读取一个名为"publish_city.csv"的CSV文件,并统计每个城市在该文件中出现的次数。首先,使用pandas库的read_csv函数读取CSV文件数据,并将其保存到变量data中。然后,使用numpy库的unique函数获取data中唯一的城市值和每个城市值的出现次数,并将结果保存到变量unique_values和counts中。接下来,使用循环遍历unique_values和counts,分别将城市和对应的人数打印出来

核心代码如图12所示:

import jieba
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import wordcloud
# 读取csv文件
data = pd.read_csv('publish_city.csv')
# 获取数组中唯一的值和每种值的出现次数
unique_values, counts = np.unique(data, return_counts=True)
# 打印每种类型数据的个数和个数总和
for city, num in zip(unique_values, counts):
    print("城市", city, "的人数为:", num)

12 数据可视化分析代码

2首先,设置了图形的大小和分辨率。然后,使用plt.rc("font",family="SimHei")来设置字体为中文,以便显示中文字符。接着绘制了折线图,并p绘制了折线上的散点。创建了y轴刻度列表。然后使用plt.yticks(y_ticks[::5])设置了y轴刻度的显示,每隔5个刻度显示一个值。使用plt.grid(True, linestyle='--', alpha=0.5)添加了网格线,并设置了线型和透明度。设置了x轴标签,并通过rotation=90使其垂直显示。使用plt.ylabel("人数",fontdict={'size': 16})设置了y轴标签。设置了图形的标题。最后使用plt.show()显示了绘制的图形。

核心代码如图13所示:

plt.figure(figsize=(100, 10), dpi=80)  # 设置画布大小和分辨率
plt.rc("font",family="SimHei")  # 设置字体为中文
plt.plot(unique_values, counts, c='red')  # 绘制折线图
plt.scatter(unique_values, counts, c='red')  # 绘制散点图
y_ticks = range(120)  # 设置y轴刻度范围
plt.yticks(y_ticks[::5])  # 设置y轴刻度间隔为5
plt.grid(True, linestyle='--', alpha=0.5)  # 添加网格线
plt.xlabel("城市", fontdict={'size': 16})  # 设置x轴标签
plt.xticks(rotation=90)  # 设置x轴刻度旋转角度为90度
plt.ylabel("人数",fontdict={'size': 16})  # 设置y轴标签
plt.title("评论者的城市分布情况", fontdict={'size': 16})  # 设置图表标题
plt.show()  # 显示图表

13 数据可视化图标代码

运行结果如图14所示:

14 数据可视化分析图标运行结果

2根据图表所获取的数组,把字符串另存一个csv文件,然后对存储的内容进行分词,创建一个字典用来存储数据,然后统计词频,使用循环遍历,然后输出显示词云,关闭坐标抽显示,最后展示词云。

核心代码如图15所示:

#词云
#使用join函数将data['用户城市']中的元素以分号(';')连接成一个字符串
title=';'.join([ str(c) for c in data['用户城市'].tolist()])
#使用jieba库的lcut函数对字符串进行分词,生成一个列表
gen=jieba.lcut(title)
#创建一个空字典data,用于统计词频
data={}
#遍历分词后的列表gen
for i in gen:
    if len(str(i))>1:
        # 如果大于1,则将该词作为字典data的key,value为该词的词频
        # 如果该词已经在字典data中,则将其value加1
        data[i] = data.get(i,0)+1
# 创建词云对象
cloud=wordcloud.WordCloud(background_color='white',font_path='C:/Windows/Fonts/方正粗黑宋简体.ttf')
# 生成云图,从给定的频率数据中
cloud.generate_from_frequencies(frequencies=data)
plt.figure(dpi=120) #分辨率
# 显示词云图
plt.imshow(cloud,interpolation='bilinear')
# 不显示坐标轴
plt.axis('off')
#展示
plt.show()

15 数据可视化分析词云代码

运行结果如图16所示:

16数据可视化分析词云代码

可视化分析的结论为:

评论数量最多的前 5 个城市排名为:

北京、上海、四川成都、广东广州、浙江杭州

三、总结

在我的课设实验中,我学习了爬虫的网页分类、爬取和解析网页的流程。为了获取网页的源代码,我使用了requests库。然后,我使用了Xpath语法掌握了其使用规则,通过使用lxml等工具对数据进行解析。使用这几个库爬取了电影的信息,电影影评和城市数据。在数据解析的过程中,我还学习了wordcloud库和matplotlib库来进行可视化处理,绘制了折线图更方便显示统计好的数据信息,还学习了jieba、numpy和pandas库用于数据的处理和分析,制作词云,使用了这几个库。通过这些学习和实践,我能够有效地爬取网页数据,并对其进行分类和解析。同时,我也能够利用各种工具和库对数据进行处理、分析和可视化展示。总的来说,这个课设实验使我对爬虫和数据解析有了更深入的理解,并且熟悉了一些常用的工具和库。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值