【问题标题】:Save data from ArcGIS feature layer从 ArcGIS 要素图层保存数据
【发布时间】:2020-11-13 10:33:50
【问题描述】:

我一直在分析我每天从 ArcGIS 地图中的要素图层手动收集的数据(链接如下)。我想自动化这个过程,并且一直在寻找使用 RESTful API(或其他东西)来收集这些信息的方法。

任务是将这个表(下面的屏幕截图)保存为我可以操作的python数据框。

我尝试使用 GET 语句的组合和 id 键的组合,但我不熟悉 API 和网络抓取。

这个任务可行吗?实现起来相当简单吗?对于 Python 中级但不熟悉网络抓取的人来说,从哪里开始?

谢谢!

链接:http://erieny.maps.arcgis.com/apps/opsdashboard/index.html#/dd7f1c0c352e4192ab162a1dfadc58e1

screenshot of website with desired information in yellow square

【问题讨论】:

    标签: python rest web-scraping arcgis


    【解决方案1】:

    这个网站几乎完全是用 javascript 制作的。话虽如此,当它使用 HTTP 请求从 API 生成数据时,可以获得您想要的信息。找到 API 并发出它需要的特定请求,您可以从中获取信息。

    为此,我们需要使用 chrome 工具网络选项卡。然后搜索我们知道应该在数据中的东西。我尝试了“14001”,因为我知道它必须在数据中。

    因此您可以在此处看到我们已搜索到正确的数据。向下滚动网络工具的 XHR 部分,可以看到请求 URL 和所有参数。

    现在,为了让您自己更轻松,您应该将请求复制为此处所示的 CURL(BASH)。您可以将其复制到 curl.trillworks.com,这将使用 requests 库将该请求转换为 python。

    话虽如此,现在使用标头和正确的参数很容易获得正确的数据。

    代码示例

    import requests
    import pandas as pd
    
    headers = {
        'Referer': 'http://erieny.maps.arcgis.com/apps/opsdashboard/index.html',
        'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Mobile Safari/537.36',
    }
    
    params = (
        ('f', 'json'),
        ('where', '1=1'),
        ('returnGeometry', 'false'),
        ('spatialRel', 'esriSpatialRelIntersects'),
        ('outFields', '*'),
        ('orderByFields', 'ZIP_CODE asc'),
        ('resultOffset', '0'),
        ('resultRecordCount', '80'),
        ('resultType', 'standard'),
        ('cacheHint', 'true'),
    )
    
    response = requests.get('https://services1.arcgis.com/CgOSc11uky3egK6O/arcgis/rest/services/erie_zip_codes_confirmed_counts/FeatureServer/0/query', headers=headers, params=params)
    
    
    data = response.json()['features']
    lists = []
    for a in data:
        zipcode = a['attributes']['ZIP_CODE']
        confirmed =a['attributes']['CONFIRMED']
        lists.append((zipcode,confirmed))
    
    df = pd.DataFrame(lists,columns=['Zip Code','Confirmed Cases'])
    

    列表输出

    [('14001', 39),
     ('14004', 70),
     ('14006', 30),
     ('14013', 0),
     ('14025', 11),
     ('14026', 4),
     ('14030', 2),
     ('14031', 84),
     ('14032', 48),
     ('14033', 3),
     ('14034', 1),....]
    

    数据帧的输出

        Zip Code    Confirmed Cases
    0   14001            39
    1   14004            70
    2   14006            30
    3   14013             0
    4   14025            11
    ...  ...            ...
    
    61  14225           257
    62  14226           187
    63  14227           260
    64  14228           128
    65  14260            0
    

    解释

    我们正在导入 requests 库,它可以轻松处理 HTTP 请求。

    requests.get() 方法处理我们提供给它的 URL 并将响应返回给我们。在这种情况下,响应是 JSON 对象格式。在参数中,我们可以指定我们要发出请求的标头和参数。

    所以我们使用正确的参数和标头来发出请求,事实证明,提供标头和参数是绝对必要的。您可以对此进行测试,实际上我经常只是在没有任何数据的情况下发出一个简单的 GET HTTP 请求,看看它是否易于模仿。在这种情况下,您需要参数和标题。

    response.json() 方法将 JSON 对象转换为 python 字典。

    现在获取您想要的信息需要一点时间,所以我鼓励您尝试一下。

    原来所需的信息在response.json()['features'] 内。其中有一个字典列表。所以我们必须循环这个。所以 a 指的是每个列表项,它恰好是一个字典。然后,我们寻找使我们获得价值的特定键。在这种情况下,在属性键和邮政编码键中,我们可以获得邮政编码,并且在属性键中也有确认键,我们可以访问确认的值。我再次强烈建议您使用 json 对象转换的字典来感受一下。

    在这里,我将变量 zipcode 并确认为一个元组到一个列表中。然后你可以在 pandas 中使用它,如上所示。

    【讨论】:

    • 我的朋友,非常感谢您的建议!我无法使用 Chrome 获取 CURL 数据,但使用 Firefox 的网络工具获取它没有问题。从那里,我可以轻松地重新调整您的代码的用途,将我需要的所有数据放入 pandas df。甚至还有一些相关数据,例如我事先从人口普查数据中手动收集的邮政编码人口。总的来说,很好的解释。我将尝试在其他 arcGIS 地图上重用此过程并获得更多经验。节省了我几个小时的工作时间,现在我有大量数据可以让我忙碌更多小时。谢谢!
    • 欢迎您!你能在左边勾选我的答案吗?谢谢!
    猜你喜欢
    • 2020-08-08
    • 1970-01-01
    • 2019-01-09
    • 2016-11-23
    • 2015-10-27
    • 1970-01-01
    • 2019-03-29
    • 2018-10-21
    • 2021-08-10
    相关资源
    最近更新 更多