python 请求调用

项目中免不了需要调用服务的接口,可能用于前后端联调或者接口自测,但是一个大的项目中,不再是简简单单的找出url,拼接请求体就能够调用的通的,有网关、认证、参数,甚至url都是动态的,一般有时候调用不通,大部分是登录认证,headers请求头中的Cookie以及url等原因,所以如何可以无缝对接,排除自身调用的问题是很有必要的,这里记录一下我总结的经验。

1、抓包

如果有网页后台,直接登录,随意点击页面,F12-network 随意找到一请求,右击copy-curl

如果有app,则通过抓包工具随意找到一个请求,同样获取curl

用获取到curl去调用基本上不会有任何拦截的,都是能调用的通的。

2、解析curl

获取到curl,虽然改改应该也能满足要求,但是为了方便我们还是要继续下面的步骤。

在这里推荐一个网站https://curlconverter.com/#python

上面这个网站可以把curl命令转换成各种语言的代码

如果为了安全或者这个网站可能没有外网vpn访问不了的话可以自己解析curl,在这里介绍一段python代码,稍微修改了一下

代码来源:博客

# coding:utf-8
import argparse
import warnings
from shlex import split
from urllib.parse import urlparse

from w3lib.http import basic_auth_header


class CurlParser(argparse.ArgumentParser):
    def error(self, message):
        error_msg = \
            'There was an error parsing the curl command: {}'.format(message)
        raise ValueError(error_msg)


# 自定义解析的内容
curl_parser = CurlParser()
curl_parser.add_argument('url')
curl_parser.add_argument('-H', '--header', dest='headers', action='append')
curl_parser.add_argument('-X', '--request', dest='method', default='get')
curl_parser.add_argument('-d', '--data-raw', dest='data')
curl_parser.add_argument('-u', '--user', dest='auth')

safe_to_ignore_arguments = [
    ['--compressed'],
    # `--compressed` argument is not safe to ignore, but it's included here
    # because the `HttpCompressionMiddleware` is enabled by default
    ['-s', '--silent'],
    ['-v', '--verbose'],
    ['-#', '--progress-bar']
]
for argument in safe_to_ignore_arguments:
    curl_parser.add_argument(*argument, action='store_true')


def curl_to_request_kwargs(curl_command, ignore_unknown_options=True):
    """Convert a cURL command syntax to Request kwargs.
    :param str curl_command: string containing the curl command
    :param bool ignore_unknown_options: If true, only a warning is emitted when
    cURL options are unknown. Otherwise raises an error. (default: True)
    :return: dictionary of Request kwargs
    """
    curl_args = split(curl_command)
    if curl_args[0] != 'curl':
        raise ValueError('A curl command must start with "curl"')
    parsed_args, argv = curl_parser.parse_known_args(curl_args[1:])
    if argv:
        msg = 'Unrecognized options: {}'.format(', '.join(argv))
        if ignore_unknown_options:
            warnings.warn(msg)
        else:
            raise ValueError(msg)
    url = parsed_args.url
    # curl automatically prepends 'http' if the scheme is missing, but Request
    # needs the scheme to work
    parsed_url = urlparse(url)
    print(parsed_url, "parsed_url---")
    if not parsed_url.scheme:
        url = 'http://' + url
    result = {'method': parsed_args.method.upper(), 'url': url}
    headers = {}
    for header in parsed_args.headers or ():
        name, val = header.split(':', 1)
        name = name.strip()
        val = val.strip()
        headers[name] = val
    if parsed_args.auth:
        user, password = parsed_args.auth.split(':', 1)
        headers.append(('Authorization', basic_auth_header(user, password)))
    if headers:
        result['headers'] = headers
    if parsed_args.data:
        result['body'] = parsed_args.data
    return result

调用

import curl
import json
#忽略未知参数
curl_command = """
      curl 'https://www.cnblogs.com/aaronthon/ajax/GetPostStat' \
  -H 'authority: www.cnblogs.com' \
  -H 'sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"' \
  -H 'accept: application/json, text/javascript, */*; q=0.01' \
  -H 'x-requested-with: XMLHttpRequest' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36' \
  -H 'content-type: application/json; charset=UTF-8' \
  -H 'origin: https://www.cnblogs.com' \
  -H 'sec-fetch-site: same-origin' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-dest: empty' \
  -H 'referer: https://www.cnblogs.com/aaronthon/p/15123690.html' \
  -H 'accept-language: zh-CN,zh;q=0.9' \
  -H 'cookie: __gads=ID=43070ddc3f5e2a8e:T=1623831362:S=ALNI_MbqIJEUeORRxrEhx_9n4HYLAFSquQ; UM_distinctid=17a1e96d0b1318-0f8b4901b76be8-34647400-13c680-17a1e96d0b2bb8; CNZZDATA1254603060=1443878496-1624010838-https%253A%252F%252Fwww.baidu.com%252F%7C1624010838; CNZZDATA2236510=cnzz_eid%3D1609801156-1624239009-https%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1624239009; Hm_lvt_4749b5754f54fbe078544caf4c473292=1624356998; CNZZDATA1277601198=1049972810-1624363879-https%253A%252F%252Fwww.baidu.com%252F%7C1624363879; CNZZDATA1279528291=1078543730-1624587844-https%253A%252F%252Fwww.baidu.com%252F%7C1624587844; CNZZDATA1261793483=2100820107-1625027605-https%253A%252F%252Fwww.baidu.com%252F%7C1625027605; CNZZDATA1274083776=388119483-1625105398-https%253A%252F%252Fwww.baidu.com%252F%7C1625105398; CNZZDATA1280000827=996990773-1625213643-https%253A%252F%252Fwww.baidu.com%252F%7C1625213643; Hm_lvt_433c388afd6e0af1d67cfe808874c659=1625556115; CNZZDATA1273185870=174238026-1625802043-https%253A%252F%252Fwww.baidu.com%252F%7C1625802043; CNZZDATA1278813996=1164552508-1625805214-https%253A%252F%252Fwww.baidu.com%252F%7C1625805214; _ga_3Q0DVSGN10=GS1.1.1626231118.1.1.1626231119.0; _ga=GA1.2.2085777000.1623831362; CNZZDATA1279248237=261423864-1624449603-https%253A%252F%252Fwww.baidu.com%252F%7C1626399705; CNZZDATA3347352=cnzz_eid%3D1606320260-1626418330-https%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1626418330; CNZZDATA1278266132=1964028659-1626955335-https%253A%252F%252Fwww.baidu.com%252F%7C1626955335; .AspNetCore.Antiforgery.b8-pDmTq1XM=CfDJ8NACB8VE9qlHm6Ujjqxvg5DzzSK1M_MolzGCgWLTO4KPl5vwGMV6gHnnYOye9cJzCOBeH4VCrDReq197KKXMSF4hVaVxalO0u87PwnfShGffxgit-fxtb02IY7wdjCL-NXHbOV-uAENFi1HB2xRU0xk; CNZZDATA1263681353=1737044733-1630319416-%7C1630319416; CNZZDATA1271451931=876074658-1631774965-%7C1631839611; pt_s_79bcbcca=vt=1631844011488&cad=; pt_79bcbcca=uid=5POLnR66XMp02ckDjWYGWQ&nid=0&vid=EXh0rIvamRN2nrlWYBrMaQ&vn=4&pvn=1&sact=1631850230847&to_flag=0&pl=-oX-XRpgWQ0os/Wu5eefqw*pt*1631850229959; CNZZDATA1259565629=1930154993-1626747115-https%253A%252F%252Fwww.baidu.com%252F%7C1632449949; CNZZDATA1279911141=369946878-1632879537-%7C1632879537; CNZZDATA1279434643=679369842-1632886799-%7C1632886799; CNZZDATA1278749494=1138115415-1633676036-%7C1633676036; CNZZDATA1279442252=194213764-1633770093-%7C1633770093; Hm_lvt_0fd13a5a7266a9c8d0150e47da38f0cb=1634697517; CNZZDATA1278666468=767455331-1634696613-%7C1634696613; Hm_lpvt_0fd13a5a7266a9c8d0150e47da38f0cb=1634698591; CNZZDATA1255872214=453631790-1635235017-%7C1635235017; CNZZDATA1277671799=1526166247-1635847128-%7C1635847128; __utma=226521935.2085777000.1623831362.1636008577.1636008577.1; __utmc=226521935; __utmz=226521935.1636008577.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); CNZZDATA1260634208=1096512542-1636330298-%7C1636353387; Hm_lvt_0796772d2f6c0092d893025a82a53c88=1636700181; Hm_lpvt_0796772d2f6c0092d893025a82a53c88=1636700181; __gpi=00000000-0000-0000-0000-000000000000; Hm_lvt_866c9be12d4a814454792b1fd0fed295=1637141729,1637205476,1637222389,1637222410; Hm_lpvt_866c9be12d4a814454792b1fd0fed295=1637230513' \
  --data-raw '[15123690]' \
  --compressed
               """
# result = curl.curl_to_request_kwargs(curl_command)
#不忽略未知参数
result = curl.curl_to_request_kwargs(curl_command,False)
print(json.dumps(result,ensure_ascii=False))

从这里可以看出,解析完之后我们得到了请求方式、请求体、url、以及请求头。

随后我们可以摘抄出来使用,用python的request库调用。

results matching ""

    No results matching ""