**本文介绍如何爬取诸如北京等城市的空气污染物浓度数据,并附有完整代码,统统解决你们找不到数据的科研问题!干货满满!!!
2021年1月12日更新
看了很多小伙伴的评论,发现我的代码被官方给“制裁”了【设置反扒了】,前段时间一直在准备秋招和毕设就没有时间反反扒(解决不能爬去的问题),如今捣鼓了一下午,终于还是搞定了!

刚刚爬取的程序结果如下:

这是我刚刚更新的本地数据库的截图!

好了,言归正传,看一下你们需要的数据应该是长这样的

这个网站有我们需要的空气污染物数据,时间跨度为2014年1月至最新日期,完美!
那么如何才能不费吹灰之力的获取到这些数据呢[实际上我第三次爬取该网站才成功>_<]?
先介绍我在爬取过程遇到的坑!让你觉得这并不是一件容易的事,哈哈哈!
困难1:
打开开发者工具(F12),如图:

这是我第一次想要爬该网站数据的时候,遇到的反爬虫情况!这是完全不给我机会呗,连网页源代码都不让我看呗! 【放弃】
最终处理方法有两个:
第一:换浏览器,如QQ浏览器,火狐浏览器
【更新】:火狐浏览器目前也不行了,也被官方设置反扒了
第二:采用断点方式(这里不具体介绍了,尽管我一开始采用的是断点)

第三:直接在网站上输入:view-source:网址即可 【推荐】
困难2:
在获取到网页源代码之后,你会发现你想要获取的数据就在tr标签里,但是你通过Beautifulsoup、Xpath等各种方式,都无法获取数据标签,最终他只会给你返回方框的代码,而你想要的椭圆形的代码就是不给你! 【放弃】


原因: 首先我们提取标签的代码是没问题的,这是因为这样的 表格数据 是通过js渲染得到的,你所需要的数据是通过ajax请求的数据包中响应数据是经过加密的密文数据…然后你就需要进行js解密,反正过程还是挺复杂的,这让没学过js的我无能为力!
解决方案:
既然是通过ajax请求获取的数据,何不从另一个角度思考-----selenium
准备工具: Firefox浏览器并配置好他的环境 ,过程并不难,百度一下即可,这一步如果有困难的可评论在下方
这里之所以用火狐而不是Chrome,原因也是Chrome无法打开网页源代码
【更新】:火狐目前也不行了
目前正确的做法是“伪装浏览器”,因为很多网站(如淘宝等)都设置了对selenium的检测,防止他们的网站被恶意爬取,检测基本原理是检测当前浏览器窗口下的 window.navigator 对象是否包含 webdriver 这个属性。因为在正常使用浏览器的情况下,这个属性是 undefined,然而一旦我们使用了 Selenium,Selenium 会给 window.navigator 设置 webdriver 属性。很多网站就通过 JavaScript 判断如果 webdriver 属性存在,那就直接屏蔽。具体的原理我就不介绍了,直接贴代码:

from selenium import webdriver
from selenium.webdriver import ChromeOptions
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
option.add_experimental_option('useAutomationExtension', False)
browser = webdriver.Chrome(options=option)
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
})
option = webdriver.ChromeOptions()
option.add_argument("start-maximized")
option.add_argument("--disable-blink-features=AutomationControlled")
option.add_experimental_option("excludeSwitches", ["enable-automation"])
option.add_experimental_option("useAutomationExtension", False)
browser = webdriver.Chrome(options=option)
browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",{'source':'''Object.defineProperty(navigator, 'webdriver', {get: () =>false'''})

感兴趣的可以参考https://zhuanlan.zhihu.com/p/191033198
接下来对代码进行讲解:
第一步:

def get_date(url):response = requests.get(url)dates = []try:if response.status_code ==200:response = response.textsoup = BeautifulSoup(response, 'lxml')dates_ = soup.find_all('li')for i in dates_:if i.a:  # 去除空值li = i.a.text  # 提取li标签下的a标签date = re.findall('[0-9]*', li)  # ['2019', '', '12', '', '']year = date[0]month = date[2]if month and year:  # 去除不符合要求的内容date_new = '-'.join([year, month])dates.append(date_new)return datesexcept:print('数据获取失败!')

这个代码是用来获取网页中某一个城市目前所有时间,其返回结果如图:

之所以日期用这样的格式是因为该网站的url链接形式:
https://www.aqistudy.cn/historydata/daydata.php?city=北京&month=2020-07
他可以被分解为 base_url+city+month
其中,base_url = ‘https://www.aqistudy.cn/historydata/daydata.php?city=’
第二步:
在得到每个月份的url链接后,接下来就是爬取数据了,这里给大家分享一个函数,也是整个代码的 核心 -------- pandas.read_html()
这个函数专门是用来解决像表格型数据的获取的,百试百灵!
代码如下:

def spider(url):browser.get(url)df = pd.read_html(browser.page_source, header=0)[0]  # 返回第一个Dataframetime.sleep(1)if not df.empty:# print(dfs)# df.to_csv('data.csv',mode='a',index=None)return dfelse:return spider(url)  # 防止网络还没加载出来就爬取下一个url

整个代码也很简单,如果是仅仅获取到数据,并保存到csv文件的话,到这一步基本就结束了,只需要print一下即可,但是我这里是需要将获取到的数据保存到本地数据库中,并定时进行更新与维护![是不是觉得这都可以作为一个小项目写到简历里啦]
主体代码如下:

for ct in range(len(city)):list_data = []list_row = []for date in dates:url = base_url + city[ct] + '&month=' + datedf = spider(url)time.sleep(1)df['city'] = city[ct]  # 添加一列for i in range(0, df.shape[0]):  # 行for j in range(df.shape[1]):  # 列data = df.iloc[i, j]list_row.append(data)list_data.append(list_row)list_row = []for n in range(len(list_data)):sql = 'insert ignore into aqidata (DATE,AQI,GRADE,PM25,PM10,SO2,CO,NO2,O3_8h,CITY)' \' VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'x = cursor.execute(sql, (list_data[n][0], float(list_data[n][1]), list_data[n][2],float(list_data[n][3]),float(list_data[n][4]),float(list_data[n][5]),float(list_data[n][6]),float(list_data[n][7]),float(list_data[n][8]),list_data[n][9]))conn.commit()
cursor.close()  # 关闭cursor
conn.close()  # 关闭连接
browser.close()

上述代码可以实现全国各地每个时间段的数据的爬取与存储,只要你网站上有的数据我都可以爬下来,聪明的小伙伴根据这三块代码就可以实时的获取到全部数据啦!

注意:
如果想存储到数据库的话,需要提前建立数据库以及表(生怕你们跑代码出问题):

有了我这代码,还愁花钱买数据吗?根本不可能好吧!
彩蛋
彩蛋

(1)既然数据已经获取到啦,那么如何进行定时更新与维护呢?
其实可以参考我的这篇博客后半部分
—>传送门
(2)既然污染物浓度数据都获取到了,有没有获取气象因子的数据方法呢?——— 有!
参考我的这篇博客----->传送门

综上就是这次博客讲解的全部内容,全部都是干货!如果对代码有疑惑或者不理解的地方,欢迎留言评论!如果觉得博客对你有帮助的话就点赞收藏吧!
如果需要完整数据的话,可以评论/私信我哈【有偿】
完整代码:

# coding=utf-8
from selenium import webdriver
import pymysql
import pandas as pd
import time
import requests
import re
from bs4 import BeautifulSoup
from sqlalchemy.exc import IntegrityErrordef get_date(url):response = requests.get(url)dates = []try:if response.status_code ==200:response = response.textsoup = BeautifulSoup(response, 'lxml')dates_ = soup.find_all('li')for i in dates_:if i.a:  # 去除空值li = i.a.text  # 提取li标签下的a标签date = re.findall('[0-9]*', li)  # ['2019', '', '12', '', '']year = date[0]month = date[2]if month and year:  # 去除不符合要求的内容date_new = '-'.join([year, month])dates.append(date_new)return datesexcept:print('数据获取失败!')
def spider(url):browser.get(url)df = pd.read_html(browser.page_source, header=0)[0]  # 返回第一个Dataframetime.sleep(1.5)if not df.empty:# print(df)# df.to_csv('data.csv', mode='a', index=None)print(url+'数据爬取已完成')return dfelse:return spider(url)  # 防止网络还没加载出来就爬取下一个url
if __name__ == '__main__':url = 'https://www.aqistudy.cn/historydata/monthdata.php?city=%E5%8C%97%E4%BA%AC'base_url = 'https://www.aqistudy.cn/historydata/daydata.php?city='# 声明浏览器对象option = webdriver.ChromeOptions()option.add_argument("start-maximized")option.add_argument("--disable-blink-features=AutomationControlled")option.add_experimental_option("excludeSwitches", ["enable-automation"])option.add_experimental_option("useAutomationExtension", False)browser = webdriver.Chrome(options=option)browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",{'source':'''Object.defineProperty(navigator, 'webdriver', {get: () =>false'''})city = ['北京',]conn = pymysql.connect(host='localhost', user='root', db='weatherdata', passwd='12345678', charset='utf8')  # 连接数据库cursor = conn.cursor()  # 获取cursor游标dates = get_date(url)[1:]print(dates)list_data = []list_row = []for ct in range(len(city)):for date in dates:url = base_url + city[ct] + '&month=' + datedf = spider(url)# print(df)time.sleep(1.5)df['city'] = city[ct]  # 添加一列for i in range(0, df.shape[0]):  # 行for j in range(df.shape[1]):  # 列data = df.iloc[i, j]list_row.append(data)list_data.append(list_row)list_row = []# print(list_data)for n in range(len(list_data)):sql = 'insert ignore into aqidata (DATE,AQI,GRADE,PM25,PM10,SO2,CO,NO2,O3_8h,CITY)' \' VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'try:x = cursor.execute(sql, (list_data[n][0], float(list_data[n][1]), list_data[n][2],float(list_data[n][3]),float(list_data[n][4]),float(list_data[n][5]),float(list_data[n][6]),float(list_data[n][7]),float(list_data[n][8]),list_data[n][9]))except IntegrityError:print('IntegrityError happened!')conn.commit()cursor.close()  # 关闭cursorconn.close()  # 关闭连接browser.close()aqidata = pd.DataFrame(list_data,columns=['日期', 'AQI', '质量等级', 'PM2.5', 'PM10', 'SO2', 'CO', 'NO2', 'O3_8h', 'city'])print('所有数据爬取已完成!\n', aqidata)

python爬取中国空气质量在线监测平台分析数据【已更新】相关推荐

  1. 爬取中国空气质量在线监测分析平台

    1.准备,爬取的链接地址 https://www.aqistudy.cn/html/city_detail.html 2.分析 a.当打开链接后,数据已经设置好了,说明里面大部分都是js通过ajax调 ...

  2. 中国空气质量在线监测分析平台-js混淆的坑

    中国空气质量在线监测分析平台-js混淆的坑 一.背景 二.过程 1.确定加密参数 2.确定加密函数 3.处理js函数 三.总结 一.背景 分析过程参照:https://cuiqingcai.com/5 ...

  3. 中国空气质量在线监測分析平台

    中国空气质量在线监測分析平台是公益性质的软件平台,提供PM2.5及天气数据的实时查询和历史数据可视化分析,统计挖掘,眼下收录了190个城市的PM2.5及天气信息数据,主要包含PM2.5实时查询.历史曲 ...

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

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

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

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

  6. 爬取全国空气质量数据

    思路: 1.空气质量在线监测平台 https://www.aqistudy.cn/: 2.分析网站,找到历史数据查询入口:https://www.aqistudy.cn/historydata/,首页 ...

  7. java获取空气质量在线监测分析平台(PM2.5真气网)数据

    空气质量在线监测分析平台(PM2.5真气网) https://www.aqistudy.cn/ 获取实时监测数据: 通过以上信息可知请求需要携带的参数d是加密的,返回的信息也是加密的 查找getSer ...

  8. python中国最好大学排名_国内大学排名如何?用Python爬取中国大学排名

    国内大学排名如何?用Python爬取中国大学排名准备阶段需要的库robots协议上代码代码框架*获取url信息*解析信息*输出数据*主函数结果 准备阶段 新手入门,不喜勿喷,这篇文章的内容其实也是在中 ...

  9. Python爬取中国知网文献、参考文献、引证文献

    转载自博客园文章作为学习资料,代码及相关介绍非常详细.原文链接见Python爬取 中国知网文献.参考文献.引证文献

最新文章

  1. 每日一皮:前程序员离职后没人想接的代码...
  2. 安卓实训项目:基于储存卡音乐播放器实训报告5.0
  3. python 将YOLO(txt)格式的标注数据批量转换为PascalVOC(XML)格式的标注数据
  4. show processlist解析
  5. python设置字符间距_python字符串处理以及字符串格式化
  6. 单点登录终极方案之 CAS 应用及原理
  7. php中ajax用法,thinkphp中使用ajax
  8. Python批量提取Excel文件中的图片
  9. Ubuntu20.04更新源步骤
  10. MySQL数据以全量和增量方式,同步到ES搜索引擎
  11. c语言立体爱心会跳动,c语言编程实例——小球跳动
  12. Excel比较两列的值
  13. 用java观察者模式解耦经典三层架构
  14. mac下删除ntfs下的文件垃圾篓清空不干净的解决办法
  15. mysql 整除取整,MySQL小数位取整
  16. 样式和主题(Style and Theme)详解
  17. CAPL脚本中对Flexray事件的响应
  18. 高仿人人车 范围选择器
  19. 你对明星直播带货有多少误解?
  20. 《javascript语言精粹》读书笔记——函数

热门文章

  1. dependency一直报错,换各种jar包都不行
  2. 抓取得物数据出现验证码的解析思路
  3. 基于自定义gym环境的强化学习
  4. 华为软开面经(许愿OC)
  5. 审批流程 html,审批流程(标准)处理中.html
  6. Play 2.6 在Play中使用缓存
  7. Interval (mathematics)
  8. watermark知识点
  9. fprintf 函数详解
  10. Ubuntu 20.04安装CUDA失败导致系统黑屏消息nvidia 0000:01:00.0: can‘t change power state from D3cold to D0 的解决方法