这是一个完整的Python项目,用于从Bilibili网站上抓取电影排行榜数据,并将数据存储到Excel文件中,然后进行数据可视化。
首先申明,我从来没有系统学习过python,所以这个只是一个简单的python如何上手的学习笔记,灵感来源与Python爬虫以及数据可视化分析_python爬虫分析图-CSDN博客
我接下来讲述的是这个项目如何运行以及中间出现的一些报错如何解决,能让你对python和爬虫有一个基础的认知,同时能在此基础上按照自己的要求编写一个简单的python项目。
这是一个完整的Python项目,用于从Bilibili网站上抓取电影排行榜数据,并将数据存储到Excel文件中,然后进行数据可视化。
python和爬虫分别是什么?
官方解释为:Python是一种高级编程语言,因其简洁易读的语法和强大的功能而广受欢迎。它适用于各种编程任务,包括Web开发、数据分析、人工智能、自动化脚本等。Python的设计哲学强调代码的可读性和简洁性,使得开发者可以用更少的代码实现更多的功能。简单来讲就是生态环境很好,很容易上手一门编程语言。
爬虫(Web Crawler),也称为网络蜘蛛或网络机器人,是一种自动化程序,用于浏览和收集互联网上的网页内容。爬虫通过模拟人类浏览器的行为,自动访问网页并提取其中的数据。爬虫的应用非常广泛,包括搜索引擎索引、数据采集、市场分析等。
Python和爬虫的关系:
Python因其丰富的库和框架,非常适合编写爬虫程序。
以下是一些常用的Python库,用于爬虫开发:(接下来的学习中会用到,所以简单学习一下)
- Requests:用于发送HTTP请求,获取网页内容。
- BeautifulSoup:用于解析HTML和XML文档,提取数据。
- Scrapy:一个强大的爬虫框架,提供了很多高级功能,如自动处理请求、数据存储等。
- Selenium:用于自动化浏览器操作,适合处理需要JavaScript渲染的网页。
如何完成这个项目在本地的运行和修改:
首先先创建一个空项目,特别简单(选file然后选pure python )
然后直接点击创建就创建好了一个空项目,创建好的空项目结构如下:
这个时候我们直接导入代码:(将代码放入main.py文件中)
我等会会讲代码是什么意思,我们先将代码运行起来,在本地运行上
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
import re
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager
from matplotlib import rcParams
def get_html(url):
chrome_options = Options()
chrome_options.add_argument("--headless") # 无头模式
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
# 指定 Chrome 浏览器的可执行文件路径
chrome_options.binary_location = r'C:\Program Files\Google\Chrome\Application\chrome.exe' # 替换为你的 Chrome 浏览器路径
# 使用 WebDriver Manager 自动下载和管理 ChromeDriver
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=chrome_options)
driver.get(url)
# 等待页面上的特定元素加载完成
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "info")))
html = driver.page_source
driver.quit()
return html
def save(html):
soup = BeautifulSoup(html, 'html.parser')
name = [] # 电影名字
release_dates = [] # 上映时间
pls = [] # 播放量
likes = [] # 喜欢数
# 电影名字存储
for tag in soup.find_all('div', class_='info'):
bf = tag.a.string
name.append(str(bf))
print("电影名字:", name)
# 上映时间存储
for tag in soup.find_all('div', class_='detail'):
release_date = tag.find('span', class_='data-box').get_text()
# 假设上映时间格式为 "YYYY-MM-DD"
release_dates.append(release_date)
print("上映时间:", release_dates)
# 播放量存储
for tag in soup.find_all('div', class_='detail-state'):
data_boxes = tag.find_all('span', class_='data-box')
if len(data_boxes) > 0:
bf = data_boxes[0].get_text()
if '亿' in bf:
num = float(re.search(r'\d+(\.\d+)?', bf).group()) * 10000
bf = num
else:
match = re.search(r'\d+(\.\d+)?', bf)
if match:
bf = match.group()
else:
bf = '0'
pls.append(float(bf))
else:
pls.append(0.0)
print("播放量:", pls)
# 喜欢数存储
for tag in soup.find_all('div', class_='detail-state'):
data_boxes = tag.find_all('span', class_='data-box')
if len(data_boxes) > 1:
likes_text = data_boxes[1].get_text()
match = re.search(r'\d+(\.\d+)?', likes_text)
if match:
likes_text = match.group()
else:
likes_text = '0'
likes.append(float(likes_text))
else:
likes.append(0.0)
print("喜欢数:(单位万)", likes)
# 检查每个列表的长度
print(f"电影名字长度: {len(name)}")
print(f"上映时间长度: {len(release_dates)}")
print(f"播放量长度: {len(pls)}")
print(f"喜欢数长度: {len(likes)}")
# 确保所有列表的长度一致
min_length = min(len(name), len(release_dates), len(pls), len(likes))
name = name[:min_length]
release_dates = release_dates[:min_length]
pls = pls[:min_length]
likes = likes[:min_length]
# 存储至excel表格中
info = {'电影名': name, '上映时间': release_dates, '播放量(万)': pls, '喜欢数(万)': likes}
dm_file = pd.DataFrame(info)
dm_file.to_excel('Dongman.xlsx', sheet_name="电影数据分析")
return name, release_dates, pls, likes
def view(info):
# 设置中文字体
my_font = font_manager.FontProperties(fname='./data/STHeiti Medium.ttc')
# 提取信息
dm_name = info[0]
dm_release_dates = info[1]
dm_play = info[2]
dm_likes = info[3]
# 设置Matplotlib参数
rcParams['font.sans-serif'] = ['SimHei']
rcParams['axes.unicode_minus'] = False
# 移除或替换不间断空格字符
dm_name = [name.replace('\xa0', ' ') for name in dm_name]
# 播放量和喜欢数对比
fig, ax1 = plt.subplots()
plt.bar(dm_name, dm_play, color='cyan')
plt.title('播放量和喜欢数数据分析', fontproperties=my_font)
ax1.tick_params(labelsize=6)
plt.xlabel('电影名')
plt.ylabel('播放量(万)')
plt.xticks(rotation=90, color='green')
ax2 = ax1.twinx()
ax2.plot(dm_likes, color='yellow')
plt.ylabel('喜欢数(万)')
plt.plot(1, label='播放量', color="cyan", linewidth=5.0)
plt.plot(1, label='喜欢数', color="yellow", linewidth=1.0, linestyle="-")
plt.legend()
plt.savefig(r'D:\1.png', dpi=1000, bbox_inches='tight')
plt.show()
def main():
url = 'https://www.bilibili.com/v/popular/rank/movie' # 网址
html = get_html(url) # 获取返回值
info = save(html)
view(info)
if __name__ == '__main__':
main()
直接点击运行,会出现报错,所以我们下一步就是导入库文件:
主要出现报错为no module,我们就需要先将模块导入:
导入模块,配置好运行环境:根据头文件导入
运行结果为:
一个excel表格和一个图表,运行结果不在现在这个电脑上,我后面要对这个文件进行一个补充,现在写的有点乱
下面我们讲解一下代码,也讲解一下python项目的一个编写逻辑:
代码分为几个主要部分:获取网页内容、解析和存储数据、数据可视化以及主函数。
1.导入必要的库:
selenium
:自动化浏览器操作,获取动态网页内容。webdriver_manager
:自动管理ChromeDriver。BeautifulSoup
:解析HTML文档。re
:正则表达式,用于字符串匹配和提取。pandas
:数据处理和存储。matplotlib
:数据可视化。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
import re
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager
from matplotlib import rcParams
2. 获取网页内容
这个函数使用Selenium启动一个无头浏览器,访问指定的URL,并等待页面加载完成后获取网页的HTML内容。
def get_html(url):
chrome_options = Options()
chrome_options.add_argument("--headless") # 无头模式
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.binary_location = r'C:\Program Files\Google\Chrome\Application\chrome.exe' # 替换为你的 Chrome 浏览器路径
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=chrome_options)
driver.get(url)
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "info")))
html = driver.page_source
driver.quit()
return html
3. 解析和存储数据
这个函数使用BeautifulSoup解析HTML内容,提取电影名字、上映时间、播放量和喜欢数,并将这些数据存储到一个Excel文件中。
def save(html):
soup = BeautifulSoup(html, 'html.parser')
name = [] # 电影名字
release_dates = [] # 上映时间
pls = [] # 播放量
likes = [] # 喜欢数
for tag in soup.find_all('div', class_='info'):
bf = tag.a.string
name.append(str(bf))
print("电影名字:", name)
for tag in soup.find_all('div', class_='detail'):
release_date = tag.find('span', class_='data-box').get_text()
release_dates.append(release_date)
print("上映时间:", release_dates)
for tag in soup.find_all('div', class_='detail-state'):
data_boxes = tag.find_all('span', class_='data-box')
if len(data_boxes) > 0:
bf = data_boxes[0].get_text()
if '亿' in bf:
num = float(re.search(r'\d+(\.\d+)?', bf).group()) * 10000
bf = num
else:
match = re.search(r'\d+(\.\d+)?', bf)
if match:
bf = match.group()
else:
bf = '0'
pls.append(float(bf))
else:
pls.append(0.0)
print("播放量:", pls)
for tag in soup.find_all('div', class_='detail-state'):
data_boxes = tag.find_all('span', class_='data-box')
if len(data_boxes) > 1:
likes_text = data_boxes[1].get_text()
match = re.search(r'\d+(\.\d+)?', likes_text)
if match:
likes_text = match.group()
else:
likes_text = '0'
likes.append(float(likes_text))
else:
likes.append(0.0)
print("喜欢数:(单位万)", likes)
print(f"电影名字长度: {len(name)}")
print(f"上映时间长度: {len(release_dates)}")
print(f"播放量长度: {len(pls)}")
print(f"喜欢数长度: {len(likes)}")
min_length = min(len(name), len(release_dates), len(pls), len(likes))
name = name[:min_length]
release_dates = release_dates[:min_length]
pls = pls[:min_length]
likes = likes[:min_length]
info = {'电影名': name, '上映时间': release_dates, '播放量(万)': pls, '喜欢数(万)': likes}
dm_file = pd.DataFrame(info)
dm_file.to_excel('Dongman.xlsx', sheet_name="电影数据分析")
return name, release_dates, pls, likes
4. 数据可视化
这个函数使用Matplotlib将数据进行可视化,生成播放量和喜欢数的对比图,并保存为图片文件。
def view(info):
my_font = font_manager.FontProperties(fname='./data/STHeiti Medium.ttc')
dm_name = info[0]
dm_release_dates = info[1]
dm_play = info[2]
dm_likes = info[3]
rcParams['font.sans-serif'] = ['SimHei']
rcParams['axes.unicode_minus'] = False
dm_name = [name.replace('\xa0', ' ') for name in dm_name]
fig, ax1 = plt.subplots()
plt.bar(dm_name, dm_play, color='cyan')
plt.title('播放量和喜欢数数据分析', fontproperties=my_font)
ax1.tick_params(labelsize=6)
plt.xlabel('电影名')
plt.ylabel('播放量(万)')
plt.xticks(rotation=90, color='green')
ax2 = ax1.twinx()
ax2.plot(dm_likes, color='yellow')
plt.ylabel('喜欢数(万)')
plt.plot(1, label='播放量', color="cyan", linewidth=5.0)
plt.plot(1, label='喜欢数', color="yellow", linewidth=1.0, linestyle="-")
plt.legend()
plt.savefig(r'D:\1.png', dpi=1000, bbox_inches='tight')
plt.show()
5.主函数
主函数调用了上述的各个函数,完成整个流程:获取网页内容、解析和存储数据、数据可视化。
def main():
url = 'https://www.bilibili.com/v/popular/rank/movie' # 网址
html = get_html(url) # 获取返回值
info = save(html)
view(info)
if __name__ == '__main__':
main()
Python项目的编写逻辑
-
明确需求:首先明确项目的目标和需求,比如本项目的目标是从Bilibili抓取电影排行榜数据,并进行数据可视化。
-
选择工具和库:根据需求选择合适的工具和库。比如本项目使用了Selenium进行网页抓取,BeautifulSoup进行HTML解析,Pandas进行数据处理,Matplotlib进行数据可视化。
-
分模块开发:将项目分成多个模块,每个模块完成一个独立的功能。比如本项目分为获取网页内容、解析和存储数据、数据可视化三个模块。