题目一:获取电影数据并写入数据库
1.题目一具体分析
进入这个网站:中国历史票房红榜 | 中国票房 | 中国电影票房排行榜,获取排行榜中所有电影的相关数据(具体字段参考下面的要求明细),并存入指定数据库中。
要求如下:
1. 数据库信息:IP:`43.143.30.32` 端口号:`3306` 用户名:`yingdao` 密码:`9527` 库名:`ydtest` 表名:`movie`(注意,该数据库只开放了写入权限,无法查询)
2. 字段及数据格式参考(提交人为影刀学院用户名!位于学院首页右上角):
电影名称 上映年份 制片地区 评分 导演 票房 提交人 长津湖 2021 中国 7.6 陈凯歌 * 577524 小迪 3. 使用编码版完成所有操作(需要在主流程调用)
4. 元素对象都要使用xpath表达式获取(禁止使用【批量数据抓取】指令)
1.1 网页分析
我们来到题目中所说的网址进行分析,发现我圈起来的红色框内的数据是我们需要获取的,但是观察到网页中的数据与我们最后需要的数据有点出入,因此我们需要对数据进行相关的处理。那么我们就需要开始请求获取数据。
因此我们直接打开pycharm,或者可以使用影刀直接创建模块,在模块中编写代码(以下所有操作均基于影刀)。
1.2 初版数据获取
在新建的影刀自动化程序中,新建一个模块,并为新建的模块命名,也可以用默认的名称。
新建的模块会有一些默认的代码以及调用,但是我们今天不使用这些,而是使用python本身的requests模块,用于网页数据获取,我们需要导入requests模块。
等待安装完成即可,至此就完成了前期的准备工作。
我们尝试获取数据。
import requests
def get_movie():
url = 'http://www.boxofficecn.com/the-red-box-office'
res = requests.get(url)
print(res.text)
在主流程中调用我们刚刚编写的模块。
我们测试一下,运行。
对比网页数据,我们发现,数据直接全部返回给我们了,因此我们就不需要进行翻页操作了,根据上面获取到的网页信息可以知道,所有的数据均在一个表的标签中,并且一些数据是结合在一起的,我们将数据分解,例如:2017 🇨🇳,这个数据是年份+国家,我们就需要将其拆解成2017+中国两个字符串;同样电影名称与评分也需要进行拆分,那么我们就需要进行详细数据获取了。
1.3 详细数据获取
根据上述分析,我们对代码进行一个调整,请出我们的xpath,新添加一个lxml的模块,安装完成后,我们就可以进行详细数据的获取了。
import re
import requests
from lxml import etree
# 缩写字母国家字典(🇨🇳_中国)
country_dict = {
'🇨🇳': '中国',
'🇺🇸': '美国',
'🇯🇵': '日本',
'🇭🇰': '香港',
'🇹🇼': '台湾',
'🇰🇷': '韩国',
'🇩🇪': '德国',
'🇫🇷': '法国',
'🇮🇹': '意大利',
'🇪🇸': '西班牙',
'🇷🇺': '俄罗斯',
"🇮🇳": '印度',
"🇬🇧": '英国',
"🇫🇮": '芬兰',
"🇱🇧": '黎巴嫩共和国',
"🇦🇺": '澳大利亚',
}
def get_movie():
url = 'http://www.boxofficecn.com/the-red-box-office'
res = requests.get(url)
res_text = etree.HTML(res.text)
tr_list = res_text.xpath('//*[@id="tablepress-4"]/tbody/tr')
result = []
for tr in tr_list:
movie_time_and_country = tr.xpath('./td[1]/text()')[0]
try:
movie_time, movie_country_words = movie_time_and_country.split(' ')
except Exception as e:
print(e)
# 正则识别年份与国家例如:2023🇨🇳,将年份2023与关键字段🇨🇳分别识别出来
movie_time = re.findall(r'\d+', movie_time_and_country)[0]
movie_country_words = movie_time_and_country.split(movie_time)[1]
print(movie_time, movie_country_words)
movie_country = country_dict[movie_country_words.strip()]
movie_name_and_score = tr.xpath('./td[2]/text()')[0]
movie_name = movie_name_and_score.split('(')[0]
movie_score = movie_name_and_score.split('(')[1].split(')')[0]
movie_actors = tr.xpath('./td[3]/text()')[0]
movie_money_list = tr.xpath('./td[last()]/font/text()') or tr.xpath('./td[last()]/text()') or []
if len(movie_money_list) == 0:
movie_money = 0
else:
try:
movie_money = int(movie_money_list[0])
except:
movie_money = int(movie_money_list[0][0:-1])
# 将数据整合成json格式
movie_dict = {
'movie_time': movie_time,
'movie_name': movie_name,
'movie_score': movie_score,
'movie_country': movie_country,
'movie_actors': movie_actors,
'movie_money': movie_money,
}
result.append(movie_dict)
print(result)
return result
运行,查看清洗过的数据是否符合我们最后插入数据库的要求,我这边是使用了一个列表,将每一个电影做成字典,最后添加到列表中。
在运行结果中可以看到,非常好的清洗了我们获取到的数据。
1.4 最终版数据整合
由题目中可知我们需要电影的详细数据,以及提交人,最后将数据写入到MySQL中;因此我决定采用元组的形式存储每一个要存储的数据。
def perfect_data(movie_data, submitter):
mysql_insert_data = []
for movie in movie_data:
movies_tuple = (
movie["movie_name"],
movie["movie_time"],
movie["movie_country"],
movie["movie_score"],
movie["movie_actors"],
movie["movie_money"],
submitter
)
mysql_insert_data.append(movies_tuple)
print(mysql_insert_data)
return mysql_insert_data
考虑到我们还要传入我们的提交人信息,因此我们将创建模块刚开始提供的main函数进行一个重新编写,submitter表示我们需要输入提交人名字。
def main(submitter):
movies_data = get_movie()
movies_datas = perfect_data(movies_data, submitter)
模块更改完成后我们主流程的调用就需要自己更改了,更改如下:
完成后,运行查看一下最后的结果是否符合我们的预期。
非常符合我们的要求,接下来就是连接数据库,将数据写入数据库中。
1.5 连接数据库并将最终数据写入数据库
连接数据库,并将数据写入数据库,因为我使用的pymysql会多一点,这边以pymysql模块为主进行展示,首先安装pymysql模块。
import pymysql
def insert_movie(movie_data):
try:
# 连接数据库
conn = pymysql.connect(host='43.143.30.32',
user='yingdao',
password='9527',
database='ydtest',
charset='utf8')
my_cursor = conn.cursor()
# sql语句
insert_sql = """
INSERT INTO movie (电影名称, 上映年份, 制片地区, 评分, 导演, 票房, 提交人)
VALUES (%s, %s, %s, %s, %s, %s, %s)
"""
for movie in movie_data:
try:
my_cursor.execute(insert_sql, movie)
conn.commit()
print(f"{movie}数据插入成功")
except Exception as e:
print(e)
conn.rollback()
print(f"{movie}数据插入失败")
except Exception as e:
print(e)
finally:
if my_cursor is not None:
my_cursor.close()
if conn is not None:
conn.close()
编写完成后,我们需要更新main函数。
def main(submitter):
movies_data = get_movie()
movies_datas = perfect_data(movies_data, submitter)
insert_movie(movies_datas)
测试通过后,这道题目就完成了~~~///(^v^)\\\~~~,运行。
成功运行,这道题目就完成了。
2.快捷使用
2.1 安装三个需要的库
pymysql
lxml
requests
2.2 模块代码
# 使用提醒:
# 1. xbot包提供软件自动化、数据表格、Excel、日志、AI等功能
# 2. package包提供访问当前应用数据的功能,如获取元素、访问全局变量、获取资源文件等功能
# 3. 当此模块作为流程独立运行时执行main函数
# 4. 可视化流程中可以通过"调用模块"的指令使用此模块
# author - 夜时雨
# time - 2025-3-19
# csdn - https://blog.csdn.net/qq_48902216
import xbot
from xbot import print, sleep
from .import package
from .package import variables as glv
# 本模块所需要的包
import re
import requests
from lxml import etree
import pymysql
# 缩写字母国家字典(🇨🇳_中国)
country_dict = {
'🇨🇳': '中国',
'🇺🇸': '美国',
'🇯🇵': '日本',
'🇭🇰': '香港',
'🇹🇼': '台湾',
'🇰🇷': '韩国',
'🇩🇪': '德国',
'🇫🇷': '法国',
'🇮🇹': '意大利',
'🇪🇸': '西班牙',
'🇷🇺': '俄罗斯',
"🇮🇳": '印度',
"🇬🇧": '英国',
"🇫🇮": '芬兰',
"🇱🇧": '黎巴嫩共和国',
"🇦🇺": '澳大利亚',
}
# 获取电影数据
def get_movie():
url = 'http://www.boxofficecn.com/the-red-box-office'
res = requests.get(url)
res_text = etree.HTML(res.text)
tr_list = res_text.xpath('//*[@id="tablepress-4"]/tbody/tr')
result = []
for tr in tr_list:
movie_time_and_country = tr.xpath('./td[1]/text()')[0]
try:
movie_time, movie_country_words = movie_time_and_country.split(' ')
except Exception as e:
print(e)
# 正则识别年份与国家例如:2023🇨🇳,将年份2023与关键字段🇨🇳分别识别出来
movie_time = re.findall(r'\d+', movie_time_and_country)[0]
movie_country_words = movie_time_and_country.split(movie_time)[1]
print(movie_time, movie_country_words)
movie_country = country_dict[movie_country_words.strip()]
movie_name_and_score = tr.xpath('./td[2]/text()')[0]
movie_name = movie_name_and_score.split('(')[0]
movie_score = movie_name_and_score.split('(')[1].split(')')[0]
movie_actors = tr.xpath('./td[3]/text()')[0]
movie_money_list = tr.xpath('./td[last()]/font/text()') or tr.xpath('./td[last()]/text()') or []
if len(movie_money_list) == 0:
movie_money = 0
else:
try:
movie_money = int(movie_money_list[0])
except:
movie_money = int(movie_money_list[0][0:-1])
# 将数据整合成json格式
movie_dict = {
'movie_time': movie_time,
'movie_name': movie_name,
'movie_score': movie_score,
'movie_country': movie_country,
'movie_actors': movie_actors,
'movie_money': movie_money,
}
result.append(movie_dict)
return result
# 最终数据
def perfect_data(movie_data, submitter):
mysql_insert_data = []
for movie in movie_data:
movies_tuple = (
movie["movie_name"],
movie["movie_time"],
movie["movie_country"],
movie["movie_score"],
movie["movie_actors"],
movie["movie_money"],
submitter
)
mysql_insert_data.append(movies_tuple)
return mysql_insert_data
# 将数据写入数据库
def insert_movie(movie_data):
try:
# 连接数据库
conn = pymysql.connect(host='43.143.30.32',
user='yingdao',
password='9527',
database='ydtest',
charset='utf8')
my_cursor = conn.cursor()
# sql语句
insert_sql = """
INSERT INTO movie (电影名称, 上映年份, 制片地区, 评分, 导演, 票房, 提交人)
VALUES (%s, %s, %s, %s, %s, %s, %s)
"""
for movie in movie_data:
try:
my_cursor.execute(insert_sql, movie)
conn.commit()
print(f"{movie}数据插入成功")
except Exception as e:
print(e)
conn.rollback()
print(f"{movie}数据插入失败")
except Exception as e:
print(e)
finally:
if my_cursor is not None:
my_cursor.close()
if conn is not None:
conn.close()
def main(submitter):
movies_data = get_movie()
movies_datas = perfect_data(movies_data, submitter)
insert_movie(movies_datas)
2.3 调用
题目二:统计电影票房数据并写入数据库
编写影刀流程从API接口(https://mock.jsont.run/6zA7NH6ciqxNxGYzKO-Zx)中获取数据,并且完成以下操作:
1. 统计出票房总数最高的三个国家,并将统计结果填写到MySQL数据库中
2. 分别统计出 3.0-3.5,9.0-9.5 和 无评分 这三个评分区间的票房总数,并将统计结果填写到MySQL数据库中
3. 数据库信息:IP:43.143.30.32 端口号:3306 用户名:yingdao 密码:9527 库名:ydtest 表名:result(注意,该数据库只开放了写入权限,无法查询)
4. 数据表结构如下(提交人为影刀学院用户名!位于学院首页右上角):
如果想查询数据是否插入成功,可以点击学院右下角的 AI 助手,选择【高级考试数据插入结果查询】功能
1.题目具体分析
1.1 网页分析
根据题目所给的网址进行分析,发现该数据为json格式的数据,并且数据均在data中。
1.2 数据获取
安装requests,pymysql模块即可。
import requests
def get_data(submitter):
url = 'https://mock.jsont.run/6zA7NH6ciqxNxGYzKO-Zx'
res = requests.get(url)
movies_data = res.json()['data']
# 统计出票房总数最高的三个国家
country_box_office = {}
rating_intervals = {
'3.0-3.5': 0,
'9.0-9.5': 0,
'无评分': 0
}
for movie in movies_data:
movie_country = movie['制片地区']
movie_money = int(movie['票房'])
movie_rating = movie.get('评分', '无评分')
if movie_country in country_box_office:
country_box_office[movie_country] += movie_money
else:
country_box_office[movie_country] = movie_money
# print(movie_rating)
if movie_rating == '-':
rating_intervals['无评分'] += movie_money
elif 3.0 <= float(movie_rating) < 3.5:
rating_intervals['3.0-3.5'] += movie_money
elif 9.0 <= float(movie_rating) < 9.5:
rating_intervals['9.0-9.5'] += movie_money
# 打印每个制片地区的票房总和
# 找出票房最高的三个国家
result = []
# 在每个数据开头都加入submitter
top_countries = sorted(country_box_office.items(), key=lambda x: x[1], reverse=True)[:3]
final_rating_intervals = [(submitter, interval, total_money) for interval, total_money in rating_intervals.items()]
top_country_list = []
for country, total_money in top_countries:
top_country_list.append((submitter, country, total_money))
result.append(top_country_list)
result.append(final_rating_intervals)
print(result)
return result
重新编写一下main函数
def main(submitter):
result_data = get_data(submitter)
主流程调用main函数
运行查看结果。
1.3 连接数据库并将数据写入到数据库
同第一题一样,更换一下sql语句即可。
import pymysql
def insert_movie(movie_data):
try:
# 连接数据库
conn = pymysql.connect(host='43.143.30.32',
port=3306,
user='yingdao',
password='9527',
database='ydtest',
charset='utf8')
my_cursor = conn.cursor()
# sql语句
insert_sql = """
INSERT INTO result (提交人, 信息, 票房总数)
VALUES (%s, %s, %s)
"""
for movie in movie_data:
try:
my_cursor.execute(insert_sql, movie)
conn.commit()
print(f"{movie}数据插入成功")
except Exception as e:
print(e)
conn.rollback()
print(f"{movie}数据插入失败")
except Exception as e:
print(e)
finally:
if my_cursor is not None:
my_cursor.close()
if conn is not None:
conn.close()
main函数重新编写。
def main(submitter):
result_data = get_data(submitter)
insert_movie(result_data[0])
insert_movie(result_data[1])
测试通过后,这道题目就完成了~~~///(^v^)\\\~~~,运行。
成功~~~,这样第二题就完成了。
2.快捷使用
2.1 安装两个需要的库
pymysql
requests
2.2 模块代码
# 使用提醒:
# 1. xbot包提供软件自动化、数据表格、Excel、日志、AI等功能
# 2. package包提供访问当前应用数据的功能,如获取元素、访问全局变量、获取资源文件等功能
# 3. 当此模块作为流程独立运行时执行main函数
# 4. 可视化流程中可以通过"调用模块"的指令使用此模块
# author - 夜时雨
# time - 2025-3-19
# csdn - https://blog.csdn.net/qq_48902216
import xbot
from xbot import print, sleep
from .import package
from .package import variables as glv
# 需要的包
import pymysql
import requests
# 获取数据,并统计数据
def get_data(submitter):
url = 'https://mock.jsont.run/6zA7NH6ciqxNxGYzKO-Zx'
res = requests.get(url)
movies_data = res.json()['data']
# 统计出票房总数最高的三个国家
country_box_office = {}
rating_intervals = {
'3.0-3.5': 0,
'9.0-9.5': 0,
'无评分': 0
}
for movie in movies_data:
movie_country = movie['制片地区']
movie_money = int(movie['票房'])
movie_rating = movie.get('评分', '无评分')
if movie_country in country_box_office:
country_box_office[movie_country] += movie_money
else:
country_box_office[movie_country] = movie_money
# print(movie_rating)
if movie_rating == '-':
rating_intervals['无评分'] += movie_money
elif 3.0 <= float(movie_rating) < 3.5:
rating_intervals['3.0-3.5'] += movie_money
elif 9.0 <= float(movie_rating) < 9.5:
rating_intervals['9.0-9.5'] += movie_money
# 打印每个制片地区的票房总和
# 找出票房最高的三个国家
result = []
# 在每个数据开头都加入submitter
top_countries = sorted(country_box_office.items(), key=lambda x: x[1], reverse=True)[:3]
final_rating_intervals = [(submitter, interval, total_money) for interval, total_money in rating_intervals.items()]
top_country_list = []
for country, total_money in top_countries:
top_country_list.append((submitter, country, total_money))
result.append(top_country_list)
result.append(final_rating_intervals)
print(result)
return result
# 将数据写入数据库
def insert_movie(movie_data):
try:
# 连接数据库
conn = pymysql.connect(host='43.143.30.32',
port=3306,
user='yingdao',
password='9527',
database='ydtest',
charset='utf8')
my_cursor = conn.cursor()
# sql语句
insert_sql = """
INSERT INTO result (提交人, 信息, 票房总数)
VALUES (%s, %s, %s)
"""
for movie in movie_data:
try:
my_cursor.execute(insert_sql, movie)
conn.commit()
print(f"{movie}数据插入成功")
except Exception as e:
print(e)
conn.rollback()
print(f"{movie}数据插入失败")
except Exception as e:
print(e)
finally:
if my_cursor is not None:
my_cursor.close()
if conn is not None:
conn.close()
def main(submitter):
result_data = get_data(submitter)
insert_movie(result_data[0])
insert_movie(result_data[1])
2.3 调用
至此,两个操作题就完成了,如果有疑问请评论留言,我会尽快回答的😉,感谢你能阅读到此处,辛苦各位了,谢谢\( ̄︶ ̄*\))