爬取数据
背景
这里是学习笔记,爬取电影网的年度票房,由于更改了网站已经从老师的以前的网站改为“https://www.endata.com.cn/BoxOffice/BO/Year”,故增加了一点点难度。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
import time
# 配置Selenium ChromeDriver
chrome_options = Options()
chrome_options.add_argument("--headless") # 无头模式,不显示浏览器窗口
driver_path = 'D:\python\chromedriver.exe' # ChromeDriver的路径
service = Service(driver_path)
for i in range(2008,2024):
# 启动Chrome浏览器
driver = webdriver.Chrome(service=service, options=chrome_options)
# 打开网页
url = "https://www.endata.com.cn/BoxOffice/BO/Year"
driver.get(url)
element = driver.find_element(By.XPATH, f"//option[@value='{i}']").click()
time.sleep(5)
# 获取完整的网页内容
html_content = driver.page_source
# 关闭浏览器
driver.quit()
# 使用BeautifulSoup解析HTML
soup = BeautifulSoup(html_content, 'html.parser')
# 使用find方法查找指定的<table>元素
table = soup.find('table', class_='bo-table img-table')
print(table)
trs=table.find_all("tr")
f=open("电影票房1.csv",mode="a")
for tr in trs:
lst=tr.find_all("td")
for td in lst:
print(td.text)
f.write(td.text)
f.write(",")
f.write("\n")
思路:
由于直接用get的方法已经获取不到数据了,故采取使用selenium库来模拟用户点击,并直接返回网页数据,则可以找到我们所要的数据
数据分析:
import pandas as pd
#这里的解释器需要用到“GBK”,中文不会出现乱码
data=pd.read_csv("电影票房1.csv", encoding='GBK',header=None)#这里我们上一部分导入的数据。
data=data.loc[:,[2,3]]
def func(item):
return item.split('/')[0]
data[4]=data[2].map(func)
def func1(item):
if '/' in item:
return item.split('/')[1]
else:
return None
data[5]=data[2].map(func1)
data_1=data.loc[:,[4,3]]
data_2=data.loc[:,[5,3]]
data_2=data_2.loc[data_2[5] != None]
data_2=data_2.rename(columns={5:4})
data=pd.concat([data_1,data_2])
#这里是关键,由于网站的改变,老师的方法需要加一点改变,这里会出现-这个另外的,需要删掉
data=data.loc[data[4]!='-']
data=data.groupby(4).mean()
data.to_csv("数据.csv")
print(data)
思路:
参考老师的方法,大体一致,小细节改变即可
数据可视化
运用flask小型开发,建立网页版可视化。
from flask import Flask,render_template
import pandas as pd
app=Flask(__name__)
@app.route('/')
def data():
df=pd.read_csv('../数据.csv')#导入数据
df=df.rename(columns={"4" : "name","3" : "value"})
df=df.to_dict(orient="records")#更改名字便于操作
print(df)
return render_template("show.html",data=df)
if __name__ == '__main__':
app.run()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.2/echarts.min.js"></script>
</head>
<body>
<div id="main" style=" width: 1900px;height: 1000px;line-height: 100px;text-align:center; background:pink"></div>
<script>
var main=echarts.init(document.getElementById("main"))
var option = {
backgroundColor: '#2c343c',
title: {
text: '电影票房',
left: 'center',
top: 20,
textStyle: {
color: '#ccc'
}
},
tooltip: {
trigger: 'item'
},
visualMap: {
show: false,
min: 10,
max: 200,
inRange: {
colorLightness: [0, 1]
}
},
series: [
{
name: 'Access From',
type: 'pie',
radius: '55%',
center: ['50%', '50%'],
data: {{data|tojson}}.sort(function (a, b) {
return a.value - b.value;
}),
roseType: 'radius',
label: {
color: 'rgba(255, 255, 255, 0.3)'
},
labelLine: {
lineStyle: {
color: 'rgba(255, 255, 255, 0.3)'
},
smooth: 0.2,
length: 10,
length2: 20
},
itemStyle: {
color: '#c23531',
shadowBlur: 200,
shadowColor: 'rgba(0, 0, 0, 0.5)'
},
animationType: 'scale',
animationEasing: 'elasticOut',
animationDelay: function (idx) {
return Math.random() * 200;
}
}
]
};
main.setOption(option)
</script>
</body>
</html>
总结
掌握selenium的方法取的数据,简单的数据清洗,以及flask简单运用,echart的引用方法