保存 ArcGIS 要素图层中的数据

Save data from ArcGIS feature layer

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

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

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

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

谢谢!

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

screenshot of website with desired information in yellow square

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

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

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

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

也就是说现在使用 headers 和正确的参数可以很容易地获得正确的数据。

代码示例

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),....]

DataFrame 的输出

    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

解释

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

requests.get() 方法处理我们提供的 URL 并返回响应。在这种情况下,响应采用 JSON object 格式。在参数中,我们可以指定 headers 和我们想要发出请求的参数。

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

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

现在需要一点时间才能得到你想要的信息,所以我鼓励你尝试一下。

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

在这里,我将变量 zipcode 和 confirmed 附加到列表中的元组中。然后,您可以在 pandas 中使用它,如上所示。