我正试图为伊利诺伊州的阿片类药物危机研究项目拉出纳洛酮分销中心的位置和名称。
可从此处访问公共卫生部门https://idph.illinois.gov/OpioidDataDashboard/
来访问此由表格生成的表格我尽了一切可能找到的东西。首先,使用Tableau的界面将URL更改为“下载”数据。那只能让我下载pdf地图,而不下载其背后的实际数据集。其次,我修改了在堆栈溢出中见过几次的python脚本,以尝试请求数据。但是,我认为它遇到了某种错误。下面的代码。
url = "https://interactive.data.illinois.gov/t/DPH/views/opioidTDWEB_prod/NaloxoneDistributionLocations"
r = requests.get(
url,
params= {
":embed":"y",
":showAppBanner":"false",
":showShareOptions":"true",
":display_count":"no",
"showVizHome": "no"
}
)
soup = BeautifulSoup(r.text, "html.parser")
print(soup)
tableauData = json.loads(soup.find("textarea",{"id": "tsConfigContainer"}).text)
dataUrl = f'https://tableau.ons.org.br{tableauData["vizql_root"]}/bootstrapSession/sessions/{tableauData["sessionid"]}'
r = requests.post(dataUrl, data= {
"sheet_id": tableauData["sheetId"],
})
dataReg = re.search('\d+;({.*})\d+;({.*})', r.text, re.MULTILINE)
info = json.loads(dataReg.group(1))
data = json.loads(dataReg.group(2))
print(data["secondaryInfo"]["presModelMap"]["dataDictionary"]["presModelHolder"]["genDataDictionaryPresModel"]["dataSegments"]["0"]["dataColumns"])
感谢任何帮助。
答案 0 :(得分:3)
由于以下各项的组合,因此有点复杂:
param
html标签动态生成的param
html标记动态构建的流程如下:
GET https://idph.illinois.gov/OpioidDataDashboard/
,将param
类别下的tableauPlaceholder
标签刮掉
主持人是:https://interactive.data.illinois.gov
从以前的param
标记中构建如下所示的“会话URL”:
GET /trusted/{ticket}/t/DPH/views/opioidTDWEB_prod/MortalityandMorbidity
上面的网址仅用于存储cookie(包括cookie中的xsrf令牌)
param
标签中构建如下所示的“配置URL”:
GET /t/DPH/views/opioidTDWEB_prod/MortalityandMorbidity
提取ID为tsConfigContainer
的文本区域并从中解析json
从上面提取的json构建“数据网址”,网址看起来像这样:
POST /vizql/t/DPH/w/opioidTDWEB_prod/v/MortalityandMorbidity/bootstrapSession/sessions/{session_id}
然后,您将在JSON响应的前面加上一些字符串,以防止json hijacking。您需要使用正则表达式来提取它,然后解析巨大的json数据
所需的所有网址都将是:
GET https://idph.illinois.gov/OpioidDataDashboard/
GET https://interactive.data.illinois.gov/trusted/yIm7jkXyRQuH9Ff1oPvz_w==:790xMcZuwmnvijXHg6ymRTrU/t/DPH/views/opioidTDWEB_prod/MortalityandMorbidity
GET https://interactive.data.illinois.gov/t/DPH/views/opioidTDWEB_prod/MortalityandMorbidity
POST https://interactive.data.illinois.gov/vizql/t/DPH/w/opioidTDWEB_prod/v/MortalityandMorbidity/bootstrapSession/sessions/2A3E3BA96A6C4E65B36AEDB4A536D09F-1:0
完整代码:
import requests
from bs4 import BeautifulSoup
import json
import re
s = requests.Session()
init_url = "https://idph.illinois.gov/OpioidDataDashboard/"
print(f"GET {init_url}")
r = s.get(init_url)
soup = BeautifulSoup(r.text, "html.parser")
paramTags = dict([
(t["name"], t["value"])
for t in soup.find("div", {"class":"tableauPlaceholder"}).findAll("param")
])
# get xsrf cookie
session_url = f'{paramTags["host_url"]}trusted/{paramTags["ticket"]}{paramTags["site_root"]}/views/{paramTags["name"]}'
print(f"GET {session_url}")
r = s.get(session_url)
config_url = f'{paramTags["host_url"][:-1]}{paramTags["site_root"]}/views/{paramTags["name"]}'
print(f"GET {config_url}")
r = s.get(config_url,
params = {
":embed": "y",
":showVizHome": "no",
":host_url": "https://interactive.data.illinois.gov/",
":embed_code_version": 2,
":tabs": "yes",
":toolbar": "no",
":showShareOptions": "false",
":display_spinner": "no",
":loadOrderID": 0,
})
soup = BeautifulSoup(r.text, "html.parser")
tableauData = json.loads(soup.find("textarea",{"id": "tsConfigContainer"}).text)
dataUrl = f'{paramTags["host_url"][:-1]}{tableauData["vizql_root"]}/bootstrapSession/sessions/{tableauData["sessionid"]}'
print(f"POST {dataUrl}")
r = s.post(dataUrl, data= {
"sheet_id": tableauData["sheetId"],
})
dataReg = re.search('\d+;({.*})\d+;({.*})', r.text, re.MULTILINE)
info = json.loads(dataReg.group(1))
data = json.loads(dataReg.group(2))
print(data["secondaryInfo"]["presModelMap"]["dataDictionary"]["presModelHolder"]["genDataDictionaryPresModel"]["dataSegments"]["0"]["dataColumns"])