1.1网站分析(抓包)

使用谷歌浏览器(火狐浏览器)的开发者工具,通过刷新监听抓取浏览器请求的响应包,找到历史数据及所有地区url等对应的包

1.1.1历史数据的数据包(get请求方式)

重庆安康: https://api.waqi.info/api/attsse/9239/yd.json 贵阳马鞍:https://api.waqi.info/api/attsse/1368/yd.json

通过对比两个地区,可发现url里面的数字即idx是变化的使用谷歌浏览器或者postman打开包后可看出数据是按照月分的,一个data对应一个月,且里面的数据是加密的,

1.1.2世界所有地区idx的(post请求方式)

Url: https://api.waqi.info/mapq2/bounds

同1.1.1方法一样可发现包里面字典键值data对应的就是不同地区的idx

1.1.3解密函数的包Url:https://aqicn.org/webapp/dist/historic-module-dyn.2b2626b6ef49374f9dcd.js

通过对网站进行断点调试,可查看到数据经过这个包里面的一些函数时,加密数据会被解析成一个月每一天的对应指标的值,

1.2爬取数据、解密数据、清洗数据并写入CSV文件

  • 通过requests的post请求方式获取到所有地区的idx,通过循环将idx写入下面url,并执行下面的操作
  • 将地区的url的idx作为变量如(https://api.waqi.info/api/attsse/{idx}/yd.json),
  • 通过requests的get请求方法获取idx对应地区的原始数据, 将图2.3、图2.4的解密函数放在一个js文件里面, 通过Execjs库调用文件里面的js函数对原始数据进行解密, 得到的数据是字典列表多重嵌套的形式, 通过键值提取需要的数据
  • 按照时间序列合并数据(二维数组类型,[[时间,pm2.5,pm10,O3,NO2,SO2,CO],])
  • 通过对city进行分割成国家/地区的形式, 通过正则替换掉一些win系统文件名不支持的字符, 用OS创建对应的目录路径(例如data/空气污染指数历史数据/CN/Guangdong/东莞/东城主山.csv), 然后使用pandas将数据写入对应路径的CSV文件

注意: 本文以学习技术为主,不可以用于非法行为, 如有侵权请联系删除

import requests
import json
import subprocess
from functools import partial
import time
import os
import pandas as pd
import re
import randomheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.7 Safari/537.36'
}subprocess.Popen = partial(subprocess.Popen, encoding="utf-8")
# 修改编码方式,window默认编码是gbk,import execjsdef get_idx():""":return: 得到所有地区的idx和name,返回列表与元组嵌套类型[(idx,name),]"""url = 'https://api.waqi.info/mapq2/bounds'data = {'bounds': "-306.21093750000006,-62.10388252289787,306.5625,78.42019327591201",'country': "",'inc': "placeholders",'viewer': "webgl",'zoom': 2}request = requests.post(url, data=data, headers=headers).texta = json.loads(request)result = []for j in a["data"]:idx = j['idx']if idx.isdigit():result.append(idx)return resultdef get_py_json(url):''':param url: 某地区url:return: 提取url加密了的的数据'''resp = requests.get(url, headers=headers).textlis = resp.split('\n\n')result = []for i in range(1, len(lis) - 1, 2):st = lis[i][18:]dic = json.loads(st)if 'msg' in dic:result.append(dic["msg"])if result:return result[1:]return resultdef get_js_function(js_path, func_name, func_args):''':param js_path: 存放解密函数的js文件:param func_name: 调用的js函数名:param func_args: 待解密数据:return: 返回解析后的数据'''with open(js_path, 'r', encoding="utf-8") as f:js = f.read()ctx = execjs.compile(js)return ctx.call(func_name, func_args)def get_decode_data(json):''':param json: 加密数据:return: 解密后的数据'''items = []for item in json:if item["ps"]:data = get_js_function('./static/js/test.js', 's', item)items.append(data)return itemsdef get_index_data(items):''':param items: 解密后的数据:return: 将不同指标分开,按照时间排序合并一起'''pm25 = []pm10 = []O3 = []NO2 = []SO2 = []CO = []time_time = []city = items[0].get('source').get('city').get('name')for item in items:for i in item["species"]:name = i['name']values = i["values"]if name == 'PM<sub>2.5</sub>':for j in i['values']:d1 = j["t"]["d"]v = j['v']time_time.append(d1)pm25.append((d1, v))if name == 'PM<sub>10</sub>':for j in i['values']:d2 = j["t"]["d"]v = j['v']time_time.append(d2)pm10.append((d2, v))if name == 'O<sub>3</sub>':for j in i['values']:d3 = j["t"]["d"]v = j['v']time_time.append(d3)O3.append((d3, v))if name == 'NO<sub>2</sub>':for j in i['values']:d4 = j["t"]["d"]v = j['v']time_time.append(d4)NO2.append((d4, v))if name == 'SO<sub>2</sub>':for j in i['values']:d5 = j["t"]["d"]v = j['v']time_time.append(d5)SO2.append((d5, v))if name == 'CO':for j in i['values']:d6 = j["t"]["d"]v = j['v']time_time.append(d6)CO.append((d6, v))time1 = list(set(time_time))date_time = []for i in time1:time_1 = time.strptime(i[:10], "%Y-%m-%d")date_time.append(time_1)date_time.sort()data_1 = []for i in date_time:data_1.append(time.strftime("%Y-%m-%d", i) + 'T00:00:00.000Z')head_list = ['时间', 'pm25', 'pm10', 'O3', 'NO2', 'SO2', 'CO']data_list = [head_list, ]for i in data_1:list_1 = [i, '', '', '', '', '', '']for pm2 in pm25:if pm2[0] == i:list_1[1] = pm2[1]for pm1 in pm10:if pm1[0] == i:list_1[2] = pm1[1]for O_3 in O3:if O_3[0] == i:list_1[3] = O_3[1]for n2 in NO2:if n2[0] == i:list_1[4] = n2[1]for s2 in SO2:if s2[0] == i:list_1[5] = s2[1]for c_1 in CO:if c_1[0] == i:list_1[6] = c_1[1]data_list.append(list_1)return data_list, citydef write_file(city, data_list):# “?”、“、”、“╲”、“/”、“*”、““”、“”“、“<”、“>”、“|”lst = re.sub(r'[?、 .╲*"<>|,]', '_', city).replace(":", "/").split("/")city_1 = '/'for i in range(0, len(lst) - 1):city_1 += lst[i] + '/'path = os.path.join("data/空气污染指数历史数据" + city_1)if not os.path.exists(path) or not os.path.isdir(path):os.makedirs(path)file_name = os.path.join(path + lst[-1] + '.csv')print(file_name)pd.DataFrame(data_list).to_csv(file_name, encoding='utf-8', index=False, header=False)def main():print("Air爬虫启动")pid = os.getpid()print("pid:", pid)with open("./data/air_pid.txt", "w") as f:f.write(str(pid))for j in range(100000):idx = get_idx()# print(len(idx))for i in idx:url = f'https://api.waqi.info/api/attsse/{i}/yd.json'with open('./data/url.txt', 'r', encoding='utf-8') as f:line = f.read().splitlines()if url not in line:try:encryption_list = get_py_json(url)decode_data = get_decode_data(encryption_list)data_list1, city = get_index_data(decode_data)print(city)write_file(city, data_list1)with open('./data/url.txt', 'a', encoding='utf-8') as f:f.write(f'{url}\n')except Exception as e:print(f"请求错误:{e}")time.sleep(5)# time.sleep(random.randint(1,10))time.sleep(random.randint(5, 10))if __name__ == '__main__':for j in range(100000):idx = get_idx()# print(len(idx))for i in idx:url = f'https://api.waqi.info/api/attsse/{i}/yd.json'with open('./data/url.txt', 'r', encoding='utf-8') as f:line = f.read().splitlines()if url not in line:try:encryption_list = get_py_json(url)decode_data = get_decode_data(encryption_list)data_list1, city = get_index_data(decode_data)print(city)write_file(city, data_list1)with open('./data/url.txt', 'a', encoding='utf-8') as f:f.write(f'{url}\n')except Exception as e:print(f"请求错误:{e}")time.sleep(5)# time.sleep(random.randint(1,10))time.sleep(random.randint(5, 10))

注意: 本文以学习技术为主,不可以用于非法行为, 如有侵权请连续删除

python 爬取 世界空气污染:空气质量指数历史数据相关推荐

  1. python爬取一年的基金历史数据,涨跌幅,净值

    之所以爬一年的,主要是一年以上参考意义不大,所以在查询日期上做了限制,其实可以爬取所有历史数据. 下面是代码: # -*- coding: utf-8 -*- """ C ...

  2. python 爬取城市空气质量数据

    [python]爬虫爬取中国城市的空气质量数据 使用工具:pycharm/python3.7,Chrome driver 使用库:selenium,time 一.下载Chrome driver(必读) ...

  3. python爬虫爬取(中国空气质量在线监测分析平台)北京PM2.5,2013年至2018年的数据

    要爬取的数据网站如下图所示: 即是爬取该网站2013年12月2日至2018年11月份北京空气质量指数历史数据,其中要爬起的 内容如PM2.5,So2等,即是从这个网页内置的表格中爬取,因为该网站比较有 ...

  4. python爬取某城市各监测站点历史空气质量数据

    python爬取某城市各监测站点历史空气质量数据 引言 正文 一.安装Web driver 二.安装selenium 三.数据爬取 引言 由于要使用某地各监测站点的空气质量数据做数据预测,因此需要去网 ...

  5. python 爬取2021年《财富》世界500强排行榜2层链接

    python  爬取2021年<财富>世界500强排行榜2层链接 ''' 2021年500强财富爬取 QQ:28928247 # ''' # -*- coding: UTF-8 -*- i ...

  6. Python爬取天气数据及可视化分析!

    来源丨Python之王 Python爬取天气数据及可视化分析 说在前面 天气预报我们每天都会关注,我们可以根据未来的天气增减衣物.安排出行,每天的气温.风速风向.相对湿度.空气质量等成为关注的焦点.本 ...

  7. Python爬取天气数据及可视化分析

    Python爬取天气数据及可视化分析 文章目录 Python爬取天气数据及可视化分析 说在前面 1.数据获取 请求网站链接 提取有用信息 保存csv文件 2.可视化分析 当天温度变化曲线图 当天相对湿 ...

  8. python爬取天气_python3爬取各类天气信息

    本来是想从网上找找有没有现成的爬取空气质量状况和天气情况的爬虫程序,结果找了一会儿感觉还是自己写一个吧. 主要是爬取北京包括北京周边省会城市的空气质量数据和天气数据. 过程中出现了一个错误:Unico ...

  9. 用python输出所有的玫瑰花数_用Python爬取WordPress官网所有插件

    转自丘壑博客,转载注明出处 前言 只要是用WordPress的人或多或少都会装几个插件,可以用来丰富扩展WordPress的各种功能.围绕WordPress平台的插件和主题已经建立了一个独特的经济生态 ...

最新文章

  1. 了解Netflix-zuul网关服务
  2. 通过日志恢复MS SQL数据案例
  3. springboot的jsp应该放在哪_在springboot中集成jsp开发
  4. Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源
  5. java类加载-ClassLoader双亲委派机制
  6. C#的变迁史07 - C# 4.0 之线程安全集合篇
  7. 二叉搜索树的中序遍历为 递增序列_Go 刷 Leetcode 系列:恢复二叉搜索树
  8. 面试官:HashMap 为什么线程不安全?
  9. distcc 链接失败_distcc分布式编译时,icu host程序偶现编译失败原因分析
  10. 【渝粤教育】国家开放大学2018年春季 0314-21T兽医基础 参考试题
  11. dgvHelper,xmlHelper,inputbox(仿vba),Evaluate(vba中函数应用于C#)
  12. 网卡驱动修改服务器,改造INTEL网卡驱动使桌面型网卡支持Windows Server 2012、2016、2019系统...
  13. MD5算法实战JS解密
  14. y的花式写法_y的花式写法_26个字母的花式写法,总有一个你喜欢哒
  15. 卷毛机器人抢大龙_LOL:机器人史诗级加强,如果他还没退役,SKT都不敢放机器人...
  16. 解决IE兼容H5的问题
  17. React - Router的基本使用介绍
  18. 计算机设备统计报告,2017年1-12月通信设备、计算机及其他电子设备制造业增加值统计分析...
  19. python从TXT导入两列数据绘图 直线多点等分坐标可视化
  20. 【活动报名】 拥抱公平《 Impact Tech, She Can 》

热门文章

  1. CSS中100%和inherit(继承)的区别,以及inherit的简单应用
  2. 教育专家李彦良谈双减后的素质教育和智慧教育
  3. Snapde电子表格编写Exprtk脚本进行数据运算
  4. python打地鼠脚本_制作一个打地鼠的小游戏!100行Python代码轻松搞定
  5. C++STL常用操作之prev、next篇
  6. 分布式体系结构:非集中式结构
  7. 中科红旗卖身内幕:收购方放言不惜代价拿下
  8. 联通家庭宽带开启ipv6
  9. Unity Shader - 羽化效果
  10. PYQT5(13)-基本窗口控件-拖曳与剪贴板