[原创]全球实时碳数据网站爬虫[全网首发 免费分享]

介绍

这几年一直很火的就是碳排放,那么关于碳数据的检测就比较重要,可能一些同学对这部分数据比较感兴趣,想要收集。

这里介绍一个网站,网站里面有一些主要国家的碳数据,涉及到的行业有:‘全国’, ‘电力’, ‘地面运输’, ‘工业’, ‘居民消费’, '国内航空’等。

网站链接: https://carbonmonitor.org.cn/user/data.php?by=WORLD

网站截图:

这里再附上几张主要截图(地区为全球,时间只显示了2020、2021年):

整体来说,可以发现数据还是相当丰富的。看着就让人心动,那么我们就把这些数据爬下来吧。

爬虫思路

找到数据位置

我把这个网站的整个数据请求链接看了好几遍,我以为数据是异步加载的,导致我翻来覆去的阅读那些js文件,但是都没找到数据异步加载的链接。我还以为是把js代码混淆加密了,结果花了好多时间去阅读js源码。

所有的办法都是尝试了一边之后,我回过头重新查看网页的主体,才发现,原来,最重要的东西都在html里面的script里面。就是数据直接写在html文件里面。我也是第一次见,数据不是异步加载,而是写到html里面😂😂

提取数据

既然已经知道数据就是在html的script脚本里面,那么我们就是把script部分的js代码提取出来就可以了。

我刚开始的思路就是,使用python的js2py或者V8eval包对js脚本做运行,然后提取里面的数据。但是两个都都失败了,

  1. js2py包运行的时候,报错了,我感觉是js可能代码有问题。放弃了,因为js代码有问题,我后面做调试的话,没什么用,不通用。
  2. V8eval包安装就没有安装成功,感觉要在系统级上安装V8才行,这个我之前使用R做爬虫的时候,用过,但是不太优雅,我都嫌安装麻烦,更不要说别人了。

最终的解决办法:我使用正则方法把数据给解析出来了,解析出:时间、类别、数据。
然后后面又做了一些简单的数据处理,最终输出一个非常清晰的数据框。

代码

我这个代码非常简单,基本上只要使用使用的Anaconda环境,大家都不需要安装别的包了。
我已经将代码放到我的GIthub上面了:https://github.com/yuanzhoulvpi2017/tiny_python/tree/main/dl_CarbonMonitor

并且也于2021-12-9日下载了一份数据放在文件夹下,截图如下:(我也额外写了一个小代码,直接下载所有地区的数据)

这里也贴一份代码:

基本脚本

import requests

from bs4 import BeautifulSoup
from itertools import chain
import re
import pandas as pd
import datetime


def get_carbon_data(by='China'):
    """
    by: 输入对应的区域,具体的可以参考这个网站
    https://carbonmonitor.org.cn/user/data.php?by=WORLD
    :return 返回数据框
    """
    location_list = ['WORLD', 'China', 'India', 'US', 'EU27', 'Russia', 'Japan',
                     'Brazil', 'UK', 'France', 'Italy', 'Germany', 'Spain', 'ROW']

    if by not in location_list:
        raise ValueError(f"你输入的 by 参数应该在这个列表内: {' ,'.join(location_list)}")
    web = requests.get(url=f"https://carbonmonitor.org.cn/user/data.php?by={by}")

    soup = BeautifulSoup(web.content, 'lxml')

    target_str = soup.find_all(name='script', attrs={'type': 'text/javascript'})[-2].string

    all_year = re.findall(pattern='''\"name\"\:(\w+)''', string=target_str)
    all_value = re.findall(pattern='''\"data\"\:\[(.*?)\]''', string=target_str)

    # type_list = ['全国', '电力', '地面运输', '工业', '居民消费', '国内航空']
    type_list = re.findall(pattern='''text\:(.*?)\<br \/\>(.*?)''', string=target_str)
    type_list = [''.join(i).replace("'", "").replace('"', "").lstrip() for i in type_list]
    type_list = list(chain(*[[i] * len(set(all_year)) for i in type_list]))
    # print(type_list)

    def generate_pd(i):
        temp_data = pd.DataFrame({'value': [float(i) for i in all_value[i].split(',')]})
        # temp_data['year'] = int(all_year[i])
        temp_data['type'] = type_list[i]
        temp_data['date'] = [datetime.date(year=int(all_year[i]), month=1, day=1) + datetime.timedelta(days=index) for
                             index in range(0, temp_data.shape[0])]
        return temp_data

    allresult = pd.concat([generate_pd(i) for i in range(0, len(all_value))])
    allresult = allresult.pivot_table(index=['date'], columns=['type'])
    allresult.columns = [i[1] for i in allresult.columns.tolist()]
    allresult = allresult.reset_index()
    return allresult

运行单块上面的代码,只是提取单个地区的数据:


# 使用脚本
get_carbon_data(by='WORLD')

批量下载脚本

因为有些人喜欢批量下载所有数据,我这里为大家也写了一个简单的下载脚本。

import os
import shutil
import time
import random

from tqdm import tqdm
dir_name = "all_region_data"


if os.path.exists(path=dir_name):
    shutil.rmtree(path=dir_name)
    os.makedirs(name=dir_name)

else:
    os.makedirs(name=dir_name)

region_list = ['WORLD', 'China', 'India', 'US', 'EU27', 'Russia', 'Japan',
                     'Brazil', 'UK', 'France', 'Italy', 'Germany', 'Spain', 'ROW']


for temp_reion in tqdm(region_list):
    time.sleep(random.random(0, 4))
    tempdata = get_carbon_data(by=temp_reion)
    tempdata.to_csv(f"{dir_name}/{temp_reion}.csv", index=False)

写在后面

  1. 感觉这个网站并不是实时更新的,可能是定期更新。
  2. 如果脚本失效了,可以找我联系(微信联系方式,就在公众号world of statistics的菜单栏的右下角),我再继续更新代码。
  3. 公众号文章的代码可能后期就失效了,大家可以去我的仓库查看最新的代码和注意事项:https://github.com/yuanzhoulvpi2017/tiny_python/tree/main/dl_CarbonMonitor
  4. 因为时间紧迫,可视化我就不做了,后面有时间的话,再水一期~
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yuanzhoulvpi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值