一.对原生python层面修改tls套件
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
CIPHERS = (
'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:RSA+3DES:!aNULL:'
'!eNULL:!MD5'
)
headers = {
'Host': 'www.ceair.com',
# 'Cookie': 'inter=NzBkYmM1NjUtZjAxNC00ZDg5LWFiNGUtYzFmZjkwNjdlMjdh; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22193006c399593a-0b3b6ad31ef90c-26011951-2073600-193006c3996837%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMTkzMDA2YzM5OTU5M2EtMGIzYjZhZDMxZWY5MGMtMjYwMTE5NTEtMjA3MzYwMC0xOTMwMDZjMzk5NjgzNyJ9%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%22%2C%22value%22%3A%22%22%7D%2C%22%24device_id%22%3A%22193006c399593a-0b3b6ad31ef90c-26011951-2073600-193006c3996837%22%7D; gr_user_id=50f8ef0b-eff3-4fde-9779-5fccfc73021e; language=zh_CN; 84bb15efa4e13721_gr_last_sent_cs1=100039802769; ceair.login.token=100039802769-785787c4-0330-4ef8-aecb-93000991334b; login_user_info_key=100039802769-785787c4-0330-4ef8-aecb-93000991334b; com.ceair.cesso=100039802769-785787c4-0330-4ef8-aecb-93000991334b; ceair.ec.trace.uid=100039802769; _c_WBKFRo=ugeymu0LXfBfbZEJgI62J2pAe2QExozdQ4tJmqRv; i18n_site=zh_CN; ssxmod_itna=eqmxgDBD0QD=G=eGHeGdfSCDUxQuD2Aw7kxETfOi8DGXxG8mDnqD=GFDK40oEMIPWWiDI4708aecDqeWlb2+H=s87GLv3mjr4GLDmKDyK284GG9xBYDQxAYDGDDpnDzwtGuD0KGRD0RkDj4GSRqGcDYj0zkG3SB4gD73DUMdDQqDSGjIqxGjZDiUyDGAZD0UXD7jZ+WiDekKiEqGWmTxD0ThCaY5Pe6=OpZXo6Qu=ZQWtVlLbxa9FfqN/zqGm4qc3mq8Z9TF38AP48i46YDxoi8GN4ExPSBx2g7w5SAx4IHI777xN/7Coz0s3DDi2tV=DxD=; ssxmod_itna2=eqmxgDBD0QD=G=eGHeGdfSCDUxQuD2Aw7kxETfODA6crYeaD/zDf2D7PPlyvBxOMK0TriCeBxCH5CqC8eOv+42ZAqWCi097wjhqLZ7qx8Y5v6Aw==MjUuqXP7VD6Qqc8FwOw+17tixSBuLc97oqYm5mKehI9OIK88AxpLhYv2hjREqemgDCfOrG0kGCQGD2YB3D8rUaOSqw86oqD+dCz627kDEaoDNVm2yhFcqPPFQC5BImeU=p6+YhoYRFaY3G8p7w5r7lFaPEHZMvw1OCkDBLz/aSmbKe8lcYwPhXdZB=ALaG56yQMKoW9IY03D07PxDLxD2WGDD==; HMF_CI=fe887c94465fb196c030096f2e8a1153ef0051646e11e7fb973f934816f44736a4109a80bdafc33d344dd1a158b2cddaa3fb27521536a2f1ead140582a07d600a4; 84bb15efa4e13721_gr_session_id=5bc2d61e-2709-44a1-aabc-f2bcaff3bd94; 84bb15efa4e13721_gr_last_sent_sid_with_cs1=5bc2d61e-2709-44a1-aabc-f2bcaff3bd94; 84bb15efa4e13721_gr_session_id_sent_vst=5bc2d61e-2709-44a1-aabc-f2bcaff3bd94; acw_tc=ac11000117319897955781117efc7325dfbec52fd15c7133ace897ceff9816; CSH_DF=72jhuBwNfd6RYjIf6YGrLdlXFZ8ac+MJ7LJ3vbabdX7VlRGWyLc3oO9Z+QEJnM9hU9; CSH_UF=7675d59b5e84e0a878ee6f0a97f9056f; gioCookie=yes; arialoadData=true; HBB_HC=5dfa23e44dea8d50cd0512034286c142a79b84e6e07e3c32f384e23bf63e5b69f1748c2e09458e722fd703f45d479a7654; 84bb15efa4e13721_gr_cs1=100039802769',
'sec-ch-ua-platform': '"Windows"',
'site': 'zh_CN',
'sec-ch-ua': '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
'x-tingyun-id': 'DuR5xFLm8eI;r=989851446',
'sec-ch-ua-mobile': '?0',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
'accept': 'application/json, text/plain, */*',
'content-type': 'application/json;charset=UTF-8;',
'origin': 'https://xxxxx.com',
'sec-fetch-site': 'same-origin',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
'referer': 'https://xxxx.com/booking-new?eyJ0cmF2ZWxUeXBlIjoib25ld2F5IiwicGFzc2VuZ2VyTnVtIjoiMSwwLDAiLCJicmFuZFByaWNlRmxhZyI6ZmFsc2UsInJlc2NoZWR1bGVGbGFnIjpmYWxzZSwiaW5mU2VhdHNOdW0iOjAsImZJZCI6bnVsbH0=encoded',
'accept-language': 'zh-CN,zh;q=0.9,en-GB;q=0.8,en-US;q=0.7,en;q=0.6',
'priority': 'u=1, i',
}
class DESAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
context = create_urllib3_context(ciphers=CIPHERS)
kwargs['ssl_context'] = context
return super(DESAdapter, self).init_poolmanager(*args, **kwargs)
def proxy_manager_for(self, *args, **kwargs):
context = create_urllib3_context(ciphers=CIPHERS)
kwargs['ssl_context'] = context
return super(DESAdapter, self).proxy_manager_for(*args, **kwargs)
url = 'http://httpbin.org/get'
s = requests.Session()
s.mount('https://xxxxxxx.com/portal/v3/booking/checkPassenger', DESAdapter())
rep = s.get(url,headers=headers)
print(rep.text)
import requests
import urllib3
url = 'https://xxxx.com/portal/v3/shopping/fareDetail'
urllib3.util.ssl_.DEFAULT_CIPHERS += 'HIGH:!DH:!aNULL'
headers = {
'accept': 'application/json, text/javascript, */*; q=0.01',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
}
r = requests.get(url=url, headers=headers)
print(r.text)
from curl_cffi import requests
url = "https://xxxxx.com/portal/v3/shopping/fareDetail"
payload = {}
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'
}
# impersonate 参数,指定了模拟哪个浏览器
r = requests.get(url,headers=headers,impersonate="chrome101")
print(r.text)
二.python random ja3
## requests
import random
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
ORIGIN_CIPHERS = ('DH+3DES:RSA+3DES:ECDH+AES256:DH+AESGCM:DH+AES256:DH+AES:ECDH+AES128:'
'DH+HIGH:RSA+AESGCM:ECDH+3DES:RSA+AES:RSA+HIGH:ECDH+AESGCM:ECDH+HIGH')
class DESAdapter(HTTPAdapter):
def __init__(self, *args, **kwargs):
CIPHERS = ORIGIN_CIPHERS.split(':')
random.shuffle(CIPHERS)
CIPHERS = ':'.join(CIPHERS)
self.CIPHERS = CIPHERS + ':!aNULL:!eNULL:!MD5'
super().__init__(*args, **kwargs)
def init_poolmanager(self, *args, **kwargs):
context = create_urllib3_context(ciphers=self.CIPHERS)
kwargs['ssl_context'] = context
return super(DESAdapter, self).init_poolmanager(*args, **kwargs)
def proxy_manager_for(self, *args, **kwargs):
context = create_urllib3_context(ciphers=self.CIPHERS)
kwargs['ssl_context'] = context
return super(DESAdapter, self).proxy_manager_for(*args, **kwargs)
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.67'}
session = requests.Session()
session.headers.update(headers)
ssl = DESAdapter()
for _ in range(5):
# 设置只绑定在 https://ja3er.com 这个网站
# s.mount('https://xxxx.com', adapter=DESAdapter())
# 设置绑定在任何 https 的请求上
session.mount('https://', adapter=ssl)
result = session.get('https://xxxx.com/portal/v3/shopping/fareDetail').json()
print(result)
##aiohttp
import asyncio
import random
import ssl
import aiohttp
ORIGIN_CIPHERS = ('RSA+3DES:RSA+AES:RSA+AESGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:ECDH+HIGH:'
'DH+HIGH:DH+3DES:RSA+HIGH:DH+AES:ECDH+3DES')
class SSLFactory:
def __init__(self):
self.ciphers = ORIGIN_CIPHERS.split(":")
def __call__(self) -> ssl.SSLContext:
random.shuffle(self.ciphers)
ciphers = ":".join(self.ciphers)
ciphers = ciphers + ":!aNULL:!eNULL:!MD5"
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.set_ciphers(ciphers)
return context
sslgen = SSLFactory()
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'}
async def main():
async with aiohttp.ClientSession() as session:
for _ in range(5):
async with session.get('https://xxxx.com/portal/v3/shopping/fareDetail', headers=headers, ssl=sslgen()) as resp:
data = await resp.text()
print(data)
asyncio.get_event_loop().run_until_complete(main())
##scrapy
1.配置文件中直接修改
# 最末尾需要确定是 :!aNULL:!eNULL:!MD5 结尾
DOWNLOADER_CLIENT_TLS_CIPHERS = 'RSA+AES:RSA+3DES:RSA+AESGCM:ECDH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:ECDH+HIGH:DH+HIGH:DH+3DES:RSA+HIGH:DH+AES:ECDH+3DES:!aNULL:!eNULL:!MD5'
2.启动自动随机修改
# 在scrapy中定义一个函数
def ssl():
ciphers = 'RSA+3DES:RSA+AES:RSA+AESGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256' \
':DH+AES256:ECDH+AES128:ECDH+HIGH:DH+HIGH:DH+3DES:RSA+HIGH:DH+AES:ECDH+3DES'.split(":")
random.shuffle(ciphers)
ciphers = ":".join(ciphers)
ciphers = ciphers + ":!aNULL:!eNULL:!MD5"
return ciphers
# 在内部进行配置参数的修改
class PaSpider(scrapy.Spider):
name = 'pa'
start_urls = ['https://ja3er.com/json']
custom_settings = {
'DOWNLOADER_CLIENT_TLS_CIPHERS': ssl(),
}
def start_requests(self):
***
##参考https://assistest.cn/2022/01/03/ja3/
三.python tls-client ja3
import random
import tls_client
client_identifier_list=[
'chrome_103',
# 'chrome_104',
# 'chrome_105',
# 'chrome_106',
# 'chrome_107',
# 'chrome_108',
# 'chrome109',
# 'Chrome110',
# 'chrome111',
# 'chrome112',
# 'firefox_102',
# 'firefox_104',
# 'firefox108',
# 'Firefox110',
# 'opera_89',
# 'opera_90',
# 'safari_15_3',
# 'safari_15_6_1',
# 'safari_16_0',
# 'safari_ios_15_5',
# 'safari_ios_15_6',
# 'safari_ios_16_0',
# 'safari_ios_15_6',
# 'okhttp4_android_7',
# 'okhttp4_android_8',
# 'okhttp4_android_9',
# 'okhttp4_android_10',
# 'okhttp4_android_11',
# 'okhttp4_android_12',
# 'okhttp4_android_13',
]
session = tls_client.Session(
client_identifier=random.choice(client_identifier_list),
random_tls_extension_order=True
)
res = session.get(
'https://xxxx.com/portal/v3/shopping/fareDetail',
headers={
"key1": "value1",
},
# proxy="http://user:password@host:port"
)
print(res.text)