python爬取jsonp_python 爬取 jsonp 请求的响应数据

jsonp  是为了解决跨域问题而诞生出的解决方案。在现代浏览器中,除了src等特殊标签可以允许跨域,其他时候都不允许跨域访问。为了解决这个问题,jsonp诞生了。

其原理主要是 向服务端传递一个一个callback 方法,以及其他请求参数。服务端接受到请求之后,收集对应参数所需要的数据,并加上之前传过来的callback 方法名 ,包装成一个内容为 js文件的响应。客户端再对这个伪js方法进行解析。

示例:

以 http://www.neeq.com.cn/zone/newshare/listofissues.html  为例

其 数据获得接口为 http://www.neeq.com.cn/newShareController/infoResult.do?callback=jQuery211_1592489332270

其中 最后的159开头的即为13位时间戳。

在浏览器中,其显示为post请求。这里我们先copy下整个headers

c48edda6262d9d7c14bc50bd2685ce3e.png

再看formdata表单,看起来也很正常00dc725bc262bdbe59c588df42fa3cff.png

我们也复制下来 。接下来我们使用requests 包模拟一下这个请求

#! /usr/bin/env python3

# -*- coding: utf-8 -*-

import requests

import time

headers = {

"Accept": "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01",

"Accept-Encoding": "gzip, deflate",

"Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",

"Cache-Control": "no-cache",

"Connection": "keep-alive",

# "Content-Length":"386", #这个需要注释掉,如果长度不对请求会被视作异常

"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",

"Cookie": "Hm_lpvt_b58fe8237d8d72ce286e1dbd2fc8308c=1592488450; BIGipServerNEEQV1.3C_WEB_8000=268501940.16415.0000; BIGipServerJY_NEEQV1.3C_WEB_8000=268501940.16415.0000; Hm_lvt_b58fe8237d8d72ce286e1dbd2fc8308c=1592515239",

"Host": "www.neeq.com.cn",

"Origin": "http://www.neeq.com.cn",

"Pragma": "no-cache",

"Referer": "http://www.neeq.com.cn/zone/newshare/listofissues.html",

"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36",

"X-Requested-With": "XMLHttpRequest",

}

formdata = {

"statetypes[]": "",

"page": "0",

"companyCode": "",

"isNewThree": "1",

"sortfield": "purchaseDate",

"sorttype": "desc",

"needFields[]": "id",

"needFields[]": "stockCode",

"needFields[]": "stockName",

"needFields[]": "initialIssueAmount",

"needFields[]": "enquiryType",

"needFields[]": "issuePrice",

"needFields[]": "peRatio",

"needFields[]": "purchaseDate",

"needFields[]": "issueResultDate",

"needFields[]": "enterPremiumDate",

}

timestamp = time.time() * 1000

url = "http://www.neeq.com.cn/newShareController/infoResult.do?callback=jQuery211_" + str(timestamp)[:13]

response = requests.get(url, headers=headers, data=formdata)

print(response.text)

#### 下面是响应内容

jQuery211_1592494024179([{"listInfo":{"content":[{"enterPremiumDate":null},{"enterPremiumDate":null}],"firstPage":true,"lastPage":true,"number":0,"numberOfElements":2,"size":20,"sort":null,"totalElements":2,"totalPages":1}}])

但是这样得出来的结果中并没有正确的数据。

我们看到 请求的url中有一个 jQuery211_xxxx的参数,这里就是jsonp方式的调用。

在浏览器中检查这个页面时,可以在http://www.neeq.com.cn/template/4/bluewise/_files/js/components/common/neeqDT.js?V_0.0.1 中得到明确的印证。这就是个jsonp请求。

最终本人经过多次模拟、搜索资料,发现 将请求url换成以下格式,并以get方式请求,即可拿到正常的数据。

url='http://www.neeq.com.cn/newShareController/infoResult.do?callback=jQuery211_{}&statetypes%5B%5D=&page=0&companyCode=&isNewThree=1&sortfield=purchaseDate&sorttype=desc&needFields%5B%5D=id&needFields%5B%5D=stockCode&needFields%5B%5D=stockName&needFields%5B%5D=initialIssueAmount&needFields%5B%5D=enquiryType&needFields%5B%5D=issuePrice&needFields%5B%5D=peRatio&needFields%5B%5D=purchaseDate&needFields%5B%5D=issueResultDate&needFields%5B%5D=enterPremiumDate'.format(str(timestamp)[:13])

这个url是接口前缀加上  时间戳callback再加上formdata拼接而成(formdata可以使用【view source】格式的数据,上文formdata图中可以找到。)

为什么换成get请求就可以了?

经查阅资料,原来jsonp只支持get。浏览器中显示的post 十分误导我们。

这里可以联系到 jsonp最终是将数据以类似src标签的方式加载,而这种加载方式的确是只有get方式。

所以以后遇见jsonp请求,一定不要误以为是post,需要找到参数拼接称get请求进行模拟即可

  • 1
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

weixin_39706367

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值