我想使用请求模块从Directory of charter schools in Ohio
下的表中获取该网站下所有页面的所有学校链接。要从下一页访问学校链接,有必要使用json参数发出发布请求。但是,我只能使用get请求访问第一个页面的链接。
当我试图处理帖子请求时,我总是得到json.decoder.JSONDecodeError:
,可能是因为我没有在标题和cookie中包含(找不到它的位置)csrftoken
。
我就是这样尝试的:
import requests
link = "https://www.causeiq.com/directory/charter-schools-list/ohio-state/"
headers = {
'referer': 'https://www.causeiq.com/directory/charter-schools-list/ohio-state/',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
}
params = {"filters":[],"pageNumber":"0","sortHow":"popularity","sortDir":"desc"}
with requests.Session() as s:
s.headers.update(headers)
resp = s.post(link,json=params)
print(resp.json())
如何生成包含学校链接的json响应?
要获得前50个项目,您可以使用以下示例(要获得更多结果,页面建议使用原因IQ搜索界面):
import requests
import pandas as pd
link = "https://www.causeiq.com/directory/charter-schools-list/ohio-state/"
headers = {
"Referer": "https://www.causeiq.com/directory/charter-schools-list/ohio-state/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
"Origin": "https://www.causeiq.com",
"X-Requested-With": "XMLHttpRequest",
}
params = {
"filters": [],
"pageNumber": "0",
"sortHow": "popularity",
"sortDir": "desc",
}
with requests.Session() as s:
# load cookies
s.get(link)
# load csrftoken token
s.get(link, headers=headers)
headers["X-CSRFToken"] = s.cookies["csrftoken"]
orgs = []
for params["pageNumber"] in range(0, 5):
data = s.post(link, json=params, headers=headers).json()
orgs.extend(data["orgs"])
df = pd.DataFrame(orgs)
print(df.head(3).to_markdown(index=False))
打印:
url | det_abbreviation="text align:left;">det_primary_address | det_year_formed | |
---|---|---|---|
/organizations/e-prep-and-village-rep,262367774/ | 262367774 | ||
501(c)(3) | |||
{'one_year_growth':61.904761904761905,'year':'2019','value':102,'series':{2019':102、'2018':63、'2017':65、'2016':73、'2015':75、'2014':111、'2013':81、'2012':59、'2011':24、'2010':24}年份:"2019","价值":7797579,"系列":{2009年:1883847,2019年:7797579,2018年:3675372,2017年:3347101,2016年:3102715,2015年:2516026,2014年:1545238,2013年:1323677,2012年:1797580,2011年:1520817,2010年:1441603})456-2070','metro':'17460','street1':'1415E 36th St','street2':无,'state':'OH','email':''} | 2008 | ||
/organizations/洛兰地平线科学院,264574311/ | 264574311 | ||
501(c)(3) | |||
2009 | |||
/组织/突破性特许学校,270362848/ | 270362848 | ||
501(c)(3) | |||
{'one_year_growth':-4.81927710843374,'year':'2018','value':79,'series':{'2018':79,'2017':83,'2016':80,'2015':53,'2014':43,'2013':35,'2012':34,'2011':34}}{2018年:817606,2017年:1482781,2016年:2247379,2015年:2214294,2014年:1894363,2013年:1502679,2012年:1587906,2011年:449131}}:'','state':'OH'} | 2009 |
首先打印resp.text并查看您实际从服务器收到的负载。(提示:是的,您需要一个csrftoken)。你可以在浏览器开发工具中找到你的csrftoken,但我不知道你是否可以使用浏览器中的一个,或者你是否必须自己生成一个。也许关于csrf的维基百科页面可以告诉你csrf是如何实现的以及如何使用令牌。其次,您需要声明您希望通过使用"application\json"作为请求标头中的内容类型。我假设网站使用Next.js,您可以通过这种方式访问服务器端渲染中的JSON数据(根据我从devtools流量中可以看出的)。