简述
2020/1/31的情况:www.pixiv.net
有污染和阻断故无法通过常规手段访问,其APP端的app-api.pixiv.net
只有污染,图床i.pximg.net
可正常访问。因此,我们可以通过Cloudflare的公众DNS获取真实ip,从而进行访问app-api.pixiv.net
,从其中的api中进行登录与查询,最终实现从图库中获取图片。(从图库中获取图片需要refer为Pixiv网域)
实现
先写代码查询DNS:
# encoding = utf-8
import requests
if __name__ == '__main__':
hostname = "app-api.pixiv.net"
url = "https://1.0.0.1/dns-query" # 查询DNS
params = {
'ct': 'application/dns-json',
'name': hostname,
'type': 'A',
'do': 'false',
'cd': 'false',
}
response = requests.get(url, params=params)
print(response.json())
Out:
{
'Status': 0,
'TC': False,
'RD': True,
'RA': True,
'AD': False,
'CD': False,
'Question': [{
'name': 'app-api.pixiv.net.',
'type': 1
}],
'Answer': [{
'name': 'app-api.pixiv.net.',
'type': 1,
'TTL': 150,
'data': '210.140.131.220'
},
{
'name': 'app-api.pixiv.net.',
'type': 1,
'TTL': 150,
'data': '210.140.131.223'
},
{
'name': 'app-api.pixiv.net.',
'type': 1,
'TTL': 150,
'data': '210.140.131.225'
}
]
}
显然,获取其中一个IP即可。接下来尝试登录:
import hashlib
from datetime import datetime
client_id = 'MOBrBDS8blbauoSck0ZfDbtuzpyT' # 假装APP应用登录
client_secret = 'lsACyCD94FhDUtGTXi3QzcFE2uU1hqtDaKeqrdwj'
hash_secret = '28c1fdd170a5204386cb1313c7077b34f83e4aaf4aa829ce78c231e05b0bae2c'
local_time = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S+00:00')
headers = {
'host': 'oauth.secure.pixiv.net',
'User-Agent': 'PixivAndroidApp/5.0.64 (Android 6.0)',
'X-Client-Time': local_time,
'X-Client-Hash': hashlib.md5((local_time + hash_secret).encode('utf-8')).hexdigest(),
'Accept-Language': 'en-us'
}
data = {
'get_secure_url': 1,
'client_id': client_id,
'client_secret': client_secret,
'grant_type': 'password', #认证类型,有token与password两种
'username': pixiv_id, # 用户名
'password': password # 密码
}
response = requests.post('https://210.140.131.220' + '/auth/token', headers=headers, data=data, stream=False,
verify=False)
print(response.text)
Out:
{
"response": {
"access_token": "omWoN1QUQ4OF9ENF4LTHObdR9K5eB1COACnOavlG5J1",
"expires_in": 3600,
"token_type": "bearer",
"scope": "",
"refresh_token": "3ysYSnD71aFttkt1XgBr-XxwjiMOGtdBmaAZbYFT2e1",
"user": {
"profile_image_urls": {
"px_16x16": "https:\/\/i.pximg.net\/user-profile\/img\/2018\/02\/11\/13\/24\/32\/13810489_848de9cbfdb78a44b1319634ccee5d31_16.jpg",
"px_50x50": "https:\/\/i.pximg.net\/user-profile\/img\/2018\/02\/11\/13\/24\/32\/13810489_848de9cbfdb78a44b1319634ccee5d31_50.jpg",
"px_170x170": "https:\/\/i.pximg.net\/user-profile\/img\/2018\/02\/11\/13\/24\/32\/13810489_848de9cbfdb78a44b1319634ccee5d31_170.jpg"
},
"id": "11111111",
"name": "Ryan",
"account": "user_ynvp1111",
"mail_address": "123456789@qq.com",
"is_premium": false,
"x_restrict": 1,
"is_mail_authorized": true
},
"device_token": "4fae17434ceedc22a7da75ca27a1a7b1"
}
}
顺便收到了一条Pixiv事务局发来的email,表明从中国登录。由上绕过SNI,成功登录并获取了bearer token,下次可以直接填入登录。
完善代码
# encoding = utf-8
import hashlib
import requests
from datetime import datetime
if __name__ == '__main__':
hostname = "app-api.pixiv.net"
timeout = 3
# url = "https://cloudflare-dns.com/dns-query"
url = "https://1.0.0.1/dns-query"
params = {
'ct': 'application/dns-json',
'name': hostname,
'type': 'A',
'do': 'false',
'cd': 'false',
}
try:
response = requests.get(url, params=params, timeout=timeout)
except Exception:
# 部分地区可能无法访问1.0.0.1,此时尝试域名解析
url = "https://cloudflare-dns.com/dns-query"
response = requests.get(url, params=params, timeout=timeout)
# response = requests.get("http://"+"210.140.131.220", params=params,headers=header())
# print(response.text)
client_id = 'MOBrBDS8blbauoSck0ZfDbtuzpyT'
client_secret = 'lsACyCD94FhDUtGTXi3QzcFE2uU1hqtDaKeqrdwj'
hash_secret = '28c1fdd170a5204386cb1313c7077b34f83e4aaf4aa829ce78c231e05b0bae2c'
local_time = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S+00:00')
headers = {
'host': 'oauth.secure.pixiv.net',
'User-Agent': 'PixivAndroidApp/5.0.64 (Android 6.0)',
'X-Client-Time': local_time,
'X-Client-Hash': hashlib.md5((local_time + hash_secret).encode('utf-8')).hexdigest(),
'Accept-Language': 'en-us'
}
data = {
'get_secure_url': 1,
'client_id': client_id,
'client_secret': client_secret,
'grant_type': 'password',
'username': pixiv_id,
'password': password
}
response = requests.post("https://" + response.json()['Answer'][0]['data'] + '/auth/token', headers=headers,
data=data, stream=False,
verify=False)
print(response.text)
登陆后可通过app-api.pixiv.net
的接口进行各类操作,IP已经获取,因此只需在IP上进行相对路径即可。
附录
常见的API及JSON格式: