selenium爬取空气质量数据

https://www.aqistudy.cn/
在这里插入图片描述
爬取指定城市在指定时间范围内的空气质量数据,并将数据保存为CSV文件。它首先从两个文本文件中读取城市信息和代理IP信息,然后提示用户输入爬取的起始年份、结束年份、起始月份和结束月份。接下来,它启动了Chrome浏览器的调试服务,并创建了一个Chrome驱动,用于自动化地访问指定的网页。之后,它定义了一个函数crawl_aqi_data(),用于爬取指定城市、指定年份和月份的空气质量数据,并将数据保存到本地文件。最后,它循环遍历所有城市和时间段,调用crawl_aqi_data()函数来完成数据爬取任务,完成后关闭浏览器,并输出"数据爬取完成。"

import os
import time
import subprocess
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.by import By
from fake_useragent import UserAgent
import random
# 读取城市信息
with open("city.txt", "r", encoding="utf-8") as file:
    cities = [line.strip() for line in file if line.strip()]

ips =[]
with open('ip.txt', 'r') as f:
    for line in f:
        ip = line.strip()
        ips.append(ip.strip())

# 输入爬取的起始年份、结束年份、起始月份和结束月份
start_year = int(input("请输入起始年份: "))
end_year = int(input("请输入结束年份: "))
start_month = int(input("请输入起始月份: "))
end_month = int(input("请输入结束月份: "))

# 启动Chrome浏览器调试服务
subprocess.Popen('cmd', shell=True)
subprocess.Popen('"chrome-win64\chrome.exe" --remote-debugging-port=9222', shell=True)

# 创建Chrome驱动
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("debuggerAddress", "localhost:9222")
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable‐gpu')
chrome_options.add_argument('--proxy-server=http://' + random.choice(ips))
chrome_options.add_argument(f"user-agent={UserAgent().random}")
driver = webdriver.Chrome(options=chrome_options)

def crawl_aqi_data(city, year, month):
    # 构建URL
    url = f"https://www.aqistudy.cn/historydata/daydata.php?city={city}&month={year}{month:02}"
    
    # 打开URL
    driver.get(url)
    time.sleep(2)  # 等待页面加载完成
    
    # 创建目录
    folder_path = os.getcwd()+f"\data\空气质量/{city}/{year}年"
    if not os.path.exists(folder_path):
        os.makedirs(folder_path)
    
    # 读取数据并保存到DataFrame
    rows = driver.find_elements(By.CSS_SELECTOR, ".row tr")
    data = []
    for row in rows:
        row_data = [cell.text for cell in row.find_elements(By.TAG_NAME, "td") if cell.text]
        if row_data:
            data.append(row_data)
    
    # 将数据转换为DataFrame
    df = pd.DataFrame(data)
    
    # 保存DataFrame为CSV文件
    file_path = f"{folder_path}/{year}{month:02}月.csv"
    df.to_csv(file_path, index=False, encoding="utf-8")
                
# 循环爬取指定城市、指定时间段的数据
for city in cities:
    for year in range(start_year, end_year + 1):
        for month in range(start_month, end_month + 1):
            crawl_aqi_data(city, year, month)
            
            
# 关闭浏览器
driver.quit()

print("数据爬取完成。")

在这里插入图片描述
数据可视化

import os
import pandas as pd
import matplotlib.pyplot as plt

# 指定数据文件夹路径
data_folder = os.path.join(os.getcwd(), 'data', '空气质量')
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


# 读取CSV文件并加载数据
def load_data(file_path):
    if os.path.exists(file_path):
        if os.stat(file_path).st_size == 0:
            print(f"File '{file_path}' is empty.")
            return None
        df = pd.read_csv(file_path)
        return df
    else:
        print(f"File '{file_path}' does not exist.")
        return None

all_df=[]
# 遍历天气目录下的城市数据
for city_name in os.listdir(data_folder):
    city_dir = os.path.join(data_folder, city_name)
    if os.path.isdir(city_dir):
        # 遍历城市文件夹下的所有 CSV 文件
        for year in os.listdir(city_dir):
            year_dir = os.path.join(city_dir, year)
            for csv_file in os.listdir(year_dir):
                if csv_file.endswith(".csv"):
                    # 构建文件路径
                    file_path = os.path.join(year_dir, csv_file)

                    # 加载数据
                    df = load_data(file_path)
                    # 添加城市列
                    df['城市'] = city_name
                    all_df.append(df)
df = pd.concat(all_df, ignore_index=True)
# 可视化显示
plt.figure(figsize=(10, 6))

plt.plot(df['城市'], df['AQI'], marker='o', color='red', linestyle='-')
plt.xlabel('城市')
plt.ylabel('AQI')
plt.title('各城市空气质量对比')
plt.xticks(rotation=90)  # 旋转x轴标签,以便更好地显示城市名
plt.grid(True)  # 显示网格线
plt.tight_layout()  # 调整布局,防止标签重叠
plt.show()

在这里插入图片描述

应该改成日期横坐标,算了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/433735.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Leetcode】3028.边界上的蚂蚁

题目描述 思路 题目中要求我们返回 蚂蚁返回到边界的次数。简单来想,就是蚂蚁原来的位置的一维坐标为0,然后经过,若干次移动,统计有几次坐标再次变为0的个数。 我们利用前缀和,像定义一个数组,算出前缀和数…

华为交换机vlan实验

一、目标 实现不同vlan之间的终端通信 二、命令学习 1.创建2个vlan # 进入系统视图 sy# 创建vlan vlan 10 vlan 202.查看vlan # 2.查看vlan display vlanThe total number of vlans is : 3 ---------------------------------------------------------------------------…

如何选择阿里云服务器配置?(CPU/内存/带宽/磁盘)

阿里云服务器配置怎么选择?CPU内存、公网带宽和系统盘怎么选择?个人开发者或中小企业选择轻量应用服务器、ECS经济型e实例,企业用户选择ECS通用算力型u1云服务器、ECS计算型c7、通用型g7云服务器,阿里云服务器网aliyunfuwuqi.com整…

Python入门教程(非常详细)从零基础入门到精通,看完这一篇就够了

前言 本文罗列了了python零基础入门到精通的详细教程,内容均以知识目录的形式展开。 第一章:python基础之markdown Typora软件下载Typora基本使用Typora补充说明编程与编程语言计算机的本质计算机五大组成部分计算机三大核心硬件操作系统 第二章&…

米哈游排名首超腾讯,登顶榜首 !!!

米哈游排名首超腾讯,登顶榜首 !!! 大家好,我是銘,全栈开发程序员。 近日,第三方机构 data.ai 公布 2023 年中国游戏厂商及应用出海收入 30 强。 其中米哈游超越腾讯,首次登顶年度…

SDM450核心板_高通SDM450安卓核心板模块性能参数

高通SDM450核心板是基于SDM450移动平台开发的一款高性能核心板。采用领先的14纳米技术,该核心板为高端智能设备提供了卓越的性能和优质的体验。板载2GB16GB的内存(可选配4GB32GB),双 ISP(图像传感器处理器)支持丰富的照片细节和双摄像头体验,…

Android大厂高级面试题灵魂100问,知识点总结+面试题解析

前言 互联网创业从火热到“寒冷”,但有一件事一直没变,就是大家都觉得招聘不到程序员。优秀的程序员也觉得很难找到合适的岗位。 “2020年技术没有成长,我今年一定要好好努力学习!” “在现在这个公司都工作了3年了,一…

Jmeter基础使用---Token鉴权接口关联

接口测试流程: 查看API接口文档,熟悉接口业务(地址、端口、参数、鉴权、状态码)设计接口测试用例(正例:正确的结果;反例:鉴权异常、参数异常、兼容异常、其他异常)使用接…

vulhub中ThinkPHP 2.x 任意代码执行漏洞复现

ThinkPHP 2.x版本中,使用preg_replace的/e模式匹配路由: $res preg_replace((\w).$depr.([^.$depr.\/])e, $var[\\\1\]"\\2";, implode($depr,$paths)); 导致用户的输入参数被插入双引号中执行,造成任意代码执行漏洞。 ThinkPH…

JAVA Thread线程——下

线程生命周期 Synchronized 死锁 释放锁

【CSP试题回顾】201503-2-数字排序

CSP-201503-2-数字排序 解题思路 数据结构定义&#xff1a;定义了 MyStruct 的结构体&#xff0c;其中包含两个成员&#xff1a;num 和 times。num 用于存储整数值&#xff0c;times 用于存储该整数出现的次数。此外&#xff0c;定义了一个 vector<MyStruct> 类型的变量…

工作中怎么去进行测试用例的编写

作为一个测试人员&#xff0c;无论是测试资深大佬还是刚入门的测试小白应该都知道&#xff0c;编写测试用例是我们测试的核心工作之一&#xff0c;往往测试用例写的标准与否&#xff0c;最能体现我们测试人员的差距&#xff0c;那么如何编写一篇优秀高质量的测试用例呢&#xf…

Flink JobGraph构建过程

文章目录 前言JobGraph创建的过程总结 前言 在StreamGraph构建过程中分析了StreamGraph的构建过程&#xff0c;在StreamGraph构建完毕之后会对StreamGraph进行优化构建JobGraph&#xff0c;然后再提交JobGraph。优化过程中&#xff0c;Flink会尝试将尽可能多的StreamNode聚合在…

资深测试总结,接口自动化测试常用配置文件(超细整理)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、常用的配置文件…

经典查找算法

经典的查找算法有几种&#xff0c;它们适用于不同的场景和数据结构。以下是一些常见的经典查找算法&#xff1a; 1. **线性查找&#xff08;Linear Search&#xff09;**&#xff1a;线性查找是一种简单直观的查找算法&#xff0c;它按顺序检查数组或列表中的每个元素&#xf…

javascript基础入门

1.第一个javascript程序 javascript程序不能够独立的运行&#xff0c;必须依赖于HTML文件&#xff0c;type属性值用来说明脚本的类型&#xff0c;这里 是指使用javascript编写的文本文件&#xff1b; 2.alert警告框 alert&#xff08;&#xff09;函数显示一条指定的信息&am…

07 外键和表关联关系

文章目录 外键约束表关联关系E-R模型图表关联查询 外键约束 约束 : 约束是一种限制&#xff0c;它通过对表的行或列的数据做出限制&#xff0c;来确保表的数据的完整性、关联性foreign key 功能 : 建立表与表之间的某种约束的关系&#xff0c;由于这种关系的存在&#xff0c;能…

论文翻译:一种基于强化学习的车辆队列控制策略,用于减少交通振荡中的能量消耗

A Reinforcement Learning-Based Vehicle Platoon Control Strategy for Reducing Energy Consumption in Traffic Oscillations 一种基于强化学习的车辆队列控制策略&#xff0c;用于减少交通振荡中的能量消耗 文章目录 A Reinforcement Learning-Based Vehicle Platoon Cont…

基础50刷题之一(交替合并字符串)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、题目二、力扣官方题解&#xff08;双指针&#xff09;三、文心一言解释总结 前言 刚上研一&#xff0c;有人劝我好好学C&#xff0c;当时用的不多就没学&a…

快速上手:剧本杀dm预约平台小程序的制作流程

在当今的娱乐市场中&#xff0c;剧本杀已经成为一种备受欢迎的娱乐方式。为了给玩家提供更好的服务和体验&#xff0c;开发一个剧本杀DM预约平台小程序是至关重要的。下面&#xff0c;我们将详细介绍如何使用乔拓云第三方平台开发这样一个预约平台。 首先&#xff0c;打开乔拓云…