python爬虫之静态网页——全国空气质量指数(AQI)爬取

本文介绍如何使用Python的requests和BeautifulSoup库从一个空气质量监测网站抓取各城市的空气质量指数(AQI)。文章详细展示了爬取过程,包括获取城市列表链接、访问各城市页面并提取AQI数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先爬取地址:http://www.air-level.com/

利用的python库,最近最流行的requests,BeautifulSoup。

requests:用于下载html

BeautifulSoup:用于解析

下面开始分析:要获取所有城市的aqi,就要进入每个城市的单独链接,而这些链接可以从主页中获取

打开主网页,查看源代码,可以看到,所有的城市链接都在id=‘citylist’里面

把所有链接爬下来存在一个列表里面,然后依次爬取每个城市的单个链接,附代码:

def get_all_city():    # 爬取城市链接
    url = "http://www.air-level.com"
    try:
        kv = {'user-agent': 'Mozilla/5.0'}  # 伪装成浏览器,headers
        r = requests.get(url, headers=kv)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
    except:
        print("爬取城市链接失败")
    demo = r.text
    soup = BeautifulSoup(demo, "html.parser")
    time = soup.find('h4').string
    print(time)
    for it in soup.find(id="citylist").children:
        if isinstance(it, bs4.element.Tag):   # 检测it的类型,得是一个bs4.element.Tag类型
            for its in it.find_all('a'):
                clist.append(its.get('href'))  # 加入列表当中去
                cnlist.append(its.string)

之后就是每个城市的单独链接的信息爬取,以北京为例,查看源代码可知:

附爬取每个城市代码:

def get_one_page(city):   # 获得HTML 爬取城市信息
    url = "http://www.air-level.com"+city
    if city in cwlink:
        aqilist.append("异常链接")
    else:
        try:
            kv = {'user-agent': 'Mozilla/5.0'}  # 伪装成浏览器,headers
            r = requests.get(url, headers=kv)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
        except:
            print("爬取失败")
        demo = r.text
        soup = BeautifulSoup(demo, "html.parser")
        s = soup.find("span")
        aqilist.append(s.string)

但是在爬取的过程中会发现问题,有的一些城市网站用浏览器打不开,也就爬取不了,所以要做处理,

在上面可以看到,本人用cwlist存储了所有异常链接,跳过去,不爬取。

附完整代码:

import requests
from bs4 import BeautifulSoup
import bs4

aqilist = []   # 储存城市AQI
clist = []     # 储存城市链接
cnlist = []    # 储存城市名字
cwlink = ["/air/changdudiqu/", "/air/kezilesuzhou/", "/air/linzhidiqu/", "/air/rikazediqu/",
          "/air/shannandiqu/", "/air/simao/", "/air/xiangfan/", "/air/yilihasake/"]   # 异常链接


def get_one_page(city):   # 获得HTML 爬取城市信息
    url = "http://www.air-level.com"+city
    if city in cwlink:
        aqilist.append("异常链接")
    else:
        try:
            kv = {'user-agent': 'Mozilla/5.0'}  # 伪装成浏览器,headers
            r = requests.get(url, headers=kv)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
        except:
            print("爬取失败")
        demo = r.text
        soup = BeautifulSoup(demo, "html.parser")
        s = soup.find("span")
        aqilist.append(s.string)


def get_all_city():    # 爬取城市链接
    url = "http://www.air-level.com"
    try:
        kv = {'user-agent': 'Mozilla/5.0'}  # 伪装成浏览器,headers
        r = requests.get(url, headers=kv)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
    except:
        print("爬取城市链接失败")
    demo = r.text
    soup = BeautifulSoup(demo, "html.parser")
    time = soup.find('h4').string
    print(time)
    for it in soup.find(id="citylist").children:
        if isinstance(it, bs4.element.Tag):   # 检测it的类型,得是一个bs4.element.Tag类型
            for its in it.find_all('a'):
                clist.append(its.get('href'))  # 加入列表当中去
                cnlist.append(its.string)


def main():
    get_all_city()
    print("共爬取了{}个城市".format(len(clist)))
    for it in range(len(clist)):
        get_one_page(clist[it])
        print("{} {}".format(cnlist[it], aqilist[it]))


main()

简单的静态爬取就实现了

爬取空气质量检测网的部分城市的历年每天质量数据 思路----------------------------------------- 从某城市的空气质量网页获取某市每月的链接,再爬取每个月的表格数据。连云港市:https://www.aqistudy.cn/historydata/daydata.php?city=连云港 连云港2014年5月的空气质量:https://www.aqistudy.cn/historydata/daydata.php?city=连云港&month=2014-05 遇到的问题----------------------------------------- 获取的网页中的表格数据隐藏,尝试requests无法获取。判断可能是动态加载的网页 尝试----------------------------------------- 1. 通过XHR,js查找隐藏数据的加载网页,没有找到。 2. 使用phantomjs.get() result=pd.read_html ,可以获得隐藏的表格数据,但是并不稳定,只是偶尔出现加载的表格数据,无法大规模的获取 解决方法----------------------------------------- 查找资料得知这个网站的表格数据在Console里的items中, 使用selenium的webdriver.firefox(),driver.execute_script("return items") 数据可获得。 仍遇到的问题:----------------------------------------- 爬取一个网页可获得数据,但是连续的获取网页,会出现两个错误。 1.Message: ReferenceError: items is not defined 2.connection refused 解决方法: 1.connection refused问题,可能是网页开太多,使用driver.quit() 2. 如果 execute_script 还是出错,可尝试pd.read_html获取信息。之前用phantomjs获取的时候输出空的表格,可能由于加载不够,用 Waite直到table出现之后再获取网页 Element=wait.until(EC.element_to_be_clickable((By.XPATH,"/html/body/div[3]/div[1]/div[1]/table/tbody"))) 3.之后出现偶尔出现输出为空,使用循环,如果输出表格为空,再重新获取。 if len(result)>1: filename = str(month) + '.xls' result.to_excel('E:\python\案例程序\data\\' + filename) print('成功存入'+filename) driver.quit() else: driver.quit() return getdata(monthhref,month)
<think>好的,用户想用Python爬取江西省的空气质量数据。首先,我需要回顾之前的引用内容,看看有没有相关的信息可以借鉴。引用2和引用3提到了爬取天气数据的方法,特别是引用2中的代码示例使用了pandas的read_html函数来抓取南昌的数据,这应该可以作为一个起点。用户的目标是江西省的数据,可能需要确定具体的城市或者覆盖全省。但空气质量数据通常分城市,可能需要遍历江西省内的所有城市页面。不过,先看看目标网站的结构。引用2中的例子是抓取南昌2022年各月的页面,URL格式是http://www.tianqihoubao.com/aqi/nanchang-2022{page}.html,这里的城市拼音是nanchang,月份用两位数字表示。所以,用户需要先获取江西省所有城市的拼音名称,或者确认是否有省级汇总页面。但可能的情况是,每个城市单独页面,需要遍历各个城市。例如,南昌、九江、赣州等。但用户可能需要先指定具体城市,或者需要爬取多个城市的数据。 另外,引用3中的项目提到使用selenium进行动态爬虫,但引用2中的例子是静态页面,用pandas就能处理。需要确认目标网站是否是动态加载的。如果页面是静态表格,用read_html可行;如果是动态生成,可能需要selenium。用户可能没有明确是否需要历史数据或实时数据。引用2中的代码是爬取2022年各月的数据,所以可能用户需要历史数据。因此,可以建议用户参考引用2的方法,调整URL中的城市和日期范围。 需要注意反爬机制,比如频繁请求可能导致IP被封。可以加入延迟,或者使用代理。此外,网站编码是gbk,需要正确设置,如引用2中的encoding='gbk'。另外,数据存储方面,引用2将数据保存到CSV文件,用户可能需要类似的方法。如果爬取多个城市,需要循环处理每个城市的URL,并可能调整文件名以区分不同城市。总结步骤:1.确定目标网站和URL结构;2.遍历江西省各城市和所需月份;3.使用pandas读取HTML表格;4.处理数据并保存。同时处理异常和反爬措施。可能的问题:城市拼音转换,比如南昌是nanchang,但其他城市的拼音可能需要核对。此外,网站是否有反爬,比如验证码或请求头检查,可能需要添加headers模拟浏览器访问。 最后,生成相关问题,帮助用户深入思考,比如如何处理反爬、数据可视化等。</think>根据引用[2]和[引用3]的爬虫实现经验,以下是江西省空气质量数据爬取方案: ### 一、爬取步骤 1. **确定数据源** 使用天气后报网站(http://www.tianqihoubao.com),该网站提供按城市分月的空气质量历史数据[^2] 2. **构造URL规则** 网站URL格式为:`http://www.tianqihoubao.com/aqi/城市拼音-年份月份.html` 例如南昌市2023年1月数据: `http://www.tianqihoubao.com/aqi/nanchang-202301.html` 3. **城市拼音对照** 江西省主要城市对应拼音: ```python city_map = { "南昌": "nanchang", "九江": "jiujiang", "赣州": "ganzhou", # 其他城市参考网站实际拼写 } ``` ### 二、完整代码实现 ```python import pandas as pd import time import logging logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s') def crawl_jiangxi_air(city_chinese, year): """爬取指定城市年度空气质量数据""" city_pinyin = city_map.get(city_chinese) if not city_pinyin: raise ValueError("城市名称错误") for month in range(1, 13): try: url = f'http://www.tianqihoubao.com/aqi/{city_pinyin}-{year}{month:02d}.html' df = pd.read_html(url, encoding='gbk')[0] # 数据清洗 df.columns = ["日期", "质量等级", "AQI", "PM2.5", "PM10", "CO", "SO2", "NO2", "O3"] df = df.iloc[1:] # 跳过标题行 # 追加写入CSV save_name = f"江西空气质量_{year}.csv" df.to_csv(save_name, mode='a', index=False, header=not pd.io.common.file_exists(save_name)) logging.info(f"{city_chinese} {year}-{month}数据已保存") time.sleep(2) # 防止反爬 except Exception as e: logging.error(f"获取{city_chinese} {month}月数据失败:{str(e)}") # 示例:爬取南昌市2023年数据 crawl_jiangxi_air("南昌", 2023) ``` ### 三、关键技术点 1. **编码处理** 网站使用GBK编码,必须指定`encoding='gbk'`才能正确解析中文[^2] 2. **反爬应对** - 设置2秒请求间隔 - 使用try-except捕获异常 - 建议添加User-Agent头部(需导入requests配合使用) 3. **数据合并** `mode='a'`参数实现多月份数据自动追加保存到同一文件 ### 四、数据可视化(引用[4]) ```python import matplotlib.pyplot as plt def visualize_aqi(csv_path): df = pd.read_csv(csv_path) df["日期"] = pd.to_datetime(df["日期"]) plt.figure(figsize=(12,6)) plt.plot(df["日期"], df["AQI"], label='AQI指数') plt.title('南昌市空气质量变化趋势') plt.xlabel('日期') plt.ylabel('AQI') plt.grid(True) plt.show() visualize_aqi("江西空气质量_2023.csv") ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值