-
Notifications
You must be signed in to change notification settings - Fork 148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cloudflare version 2 captcha on auth request #259
Comments
I tried doing what you mentioned, but then Here's what I have: import configparser
from pixivpy3 import *
api = AppPixivAPI()
config = configparser.ConfigParser(interpolation=None)
config.read('config.ini')
USERNAME = config['pixiv']['username']
PASSWORD = config['pixiv']['password']
REFRESH_TOKEN = config['pixiv']['refresh_token']
# Login with your Pixiv credentials (username and password)
api.auth(refresh_token=REFRESH_TOKEN)
# Get the user detail for the currently logged in user
user_detail = api.user_detail(api.user_id)
user = user_detail.user
# Print the user's username and user ID
print("Username: ", user.name)
print("User ID: ", user.id) This works once in a blue moon, every other attempt returns the error: Is the full command
|
Pixiv changed captcha to version 2 is a bad news, may be we can use ZenRows instead? Regarding the difference between def set_auth(self, access_token: str, refresh_token: str | None = None) -> None:
self.access_token = access_token
self.refresh_token = refresh_token
def auth(
self,
username: str | None = None,
password: str | None = None,
refresh_token: str | None = None,
headers: ParamDict = None,
) -> ParsedJson:
"""Login with password, or use the refresh_token to acquire a new bearer token"""
r = self.requests_call("POST", url, headers=headers_, data=data) |
How can I use it in conjunction with api.set_auth(ACCESS_TOKEN, REFRESH_TOKEN)
api.auth(refresh_token=REFRESH_TOKEN) |
self.requests = requests.Session()
# self.requests = cloudscraper.create_scraper() # fix due to #140 ZenRows access using a proxy (but I haven't tried), you can refer to # If a special network environment is meet, please configure requests as you need.
# Otherwise, just keep it empty.
zen_proxy = "http://APIKEY:@proxy.zenrows.com:8001"
_REQUESTS_KWARGS = {
'proxies': {
{"http": zen_proxy, "https": zen_proxy},
},
'verify': False, # PAPI use https, an easy way is disable requests SSL verify
}
api = AppPixivAPI(**_REQUESTS_KWARGS) I'm happy to get your feedback. |
My workflow right now is something like this:
(the accessToken and refreshToken variables are the values i just saved in the file when running refresh)
Notice how i used This works for me 100% of the time (or maybe i've been lucky, i don't know ahahahah), hope this helped in any way |
I vaguely understand what you have done. Are doing all of this (initial auth, refresh access_token to separate file, Would you mind sharing your code with all of these elements in together just so I can get a tangible reference? Barring your credentials of course. Because when I tried doing what you did, with brand new a access_token, I get an error: import configparser
from pixivpy3 import *
api = AppPixivAPI()
config = configparser.ConfigParser(interpolation=None)
config.read('config.ini')
USERNAME = config['pixiv']['username']
PASSWORD = config['pixiv']['password']
ACCESS_TOKEN = config['pixiv']['access_token']
REFRESH_TOKEN = config['pixiv']['refresh_token']
# Login with your Pixiv credentials (username and password)
api.set_auth(access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)
# Get the user detail for the currently logged in user
user_detail = api.user_detail(api.user_id)
user = user_detail.user
# Print the user's username and user ID
print("Username:",user.name)
print("User ID:",user.id) print(api.user_id) returns 0. |
No problem :) (don't mind the awful code, i tried to patch the errors as fast as i could) def print_auth_token_response(response):
data = response.json()
try:
access_token = data["access_token"]
refresh_token = data["refresh_token"]
except KeyError:
print("error:")
pprint(data)
exit(1)
accessTokenFile = open("access_token.txt", "w")
refreshTokenFile = open("refresh_token.txt", "w")
# Down below is what i added
# ***************************************
accessTokenFile.write(access_token)
refreshTokenFile.write(refresh_token)
# *************************************** File 2: pixiv_rand.py, In this file i use the illust_recommended function to get some sort of biased random image based on the ones i liked before but that's not the point. Before that function call is where i do the OAuth part (which i do in every file where i need to make calls to the pixiv api via the functions of pixivpy). api = AppPixivAPI()
refreshTokenFile = open("refresh_token.txt").readlines()
Popen(["python3", "pixiv_auth.py", "refresh", refreshTokenFile[0].strip()]) # this runs the "File 1" with the parameter refresh so you need to pass your refresh_token
accessTokenFile = open("access_token.txt").readlines()
api.set_auth(access_token=accessTokenFile[0].strip(), refresh_token=refreshTokenFile[0].strip()) # we pass both the refresh token and the newly acquired access_token which was just saved in the access_token.txt file in the "File 1"
json_result = api.illust_recommended(content_type=arg_content_type or "illust") Doing it this way i don't need to call the api.auth function and everything seems to work (or atleast gathering illustrations randomly or by passing tags and liking posts) I tried just now calling the function you use to get user_details and it return 0 for the api.user_id and gives an error for the api.user_detail function to me too, so maybe doing it this way doesn't give you any way to get the user_id (?) |
How do you ensure your
I suppose I haven't done anything wrong then. But in that case, how is one supposed to access their own information using your workaround. Weird... |
Right now i refresh it every time i need to call a function, so that i don't encounter any problems (to refresh it i execute the script pixiv_auth using Popen Popen(["python3", "pixiv_auth.py", "refresh", refresh_token]) and i made the thing to save the stuff to the txt files so i don't have to copy and paste everything edit: I found out something really cool that might help you, if you do api.set_auth and just then do api.auth it seems to work and also enables the api.user_id and api.user_detail stuff. api.auth(refresh_token=refreshTokenFile[0].strip()) |
What I have import configparser, json
from subprocess import Popen
from pixivpy3 import *
api = AppPixivAPI()
config = configparser.ConfigParser(interpolation=None)
config.read('config.ini')
USERNAME = config['pixiv']['username']
PASSWORD = config['pixiv']['password']
ACCESS_TOKEN = config['pixiv']['access_token']
REFRESH_TOKEN = config['pixiv']['refresh_token']
print(Popen(["python3", "pixiv_auth.py", "refresh", REFRESH_TOKEN]))
I even replaced the filename with the fullpath to the file. It's in the same directory as my script. Might have to do some scrappying changeDir workaround
I actually did ask of this earlier, I tried it and it didn't work. Was that what you mean here? |
Mh, it's strange it's not finding the file for you, could it be because i'm using linux and to run python i use the python3 command and maybe on windows it's different? like py or python? (haven't used python on windows in a while so i'm not sure)
Ah yes, mb didn't see that comment, strange, i don't know why it works for me and doesn't for you tbh, could it be that it didn't work because you wrote the function like this |
That was the issue. "python" by itself worked. Returned I assume if I add similar edits to the pixiv_auth.py file, running that Popen command could potentially update my config file with new access_tokens and refresh_tokens. config = configparser.ConfigParser()
config.read('config.ini')
config.set('pixiv', 'access_token', access_token)
config.set('pixiv', 'refresh_token', refresh_token)
with open('config.ini', 'w') as configfile:
config.write(configfile)
So I tried api.set_auth(access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)
api.auth(refresh_token=REFRESH_TOKEN) and got the error
from |
It's up to the server to decide whether a captcha will be required, which seems pretty random to us. Whether to use |
at this point it's faster to setup a proxy or something to bypass cloudflare, i think FlareSolverr could work but i've never tried doing anything like that so i can't assure anything, when i have more time i'll check out some stuff |
I'll wait around and see if a solution gets implemented into the API, since I still need to get a working program for whatever it is I need first. Thanks for staying up with me with this. There's a lot of vagueness in the documentation, I think once I get my own ball rolling, I'd like to contribute to cleaning that up and add a full EN version, since this is the only working Python wrapper for Pixiv that I'm aware of. |
No problem :) |
I think this is likely because Cloudflare's bot management system, which Pixiv uses, sosmehow detects cloudscraper (which shouldn't be used in the first place. Why would anyone request an API endpoint using a headless browser?) If anyone has the official app installed, try capturing the traffic and find out the TLS fingerprint generated by the app. Cloudflare allows customers to whitelist JA3 fingerprints and I think it's possible that Pixiv has done so to make sure their official apps don't get broken. I have no idea why the Pixiv staff think it's a good idea to put API endpoints behind Cloudflare's bot management system, since the CAPTCHA is intended for web browsers rather than apps. |
Hello, @zzAIMoo! Have you tried to log in using proxy yet? I presume if it worked out we would be able to close the issue. |
Hi sorry, i haven't tried yet because i've had almost no free time, i don't know when i'll be able to try and login using a proxy. As soon as i can i'll try and update here. (if anyone wants to do it before me so we can close the issue don't hesitate :D) |
Same problem, when I change the proxy connection, the captcha problem disappears, maybe it's a proxy quality issue. |
When trying to call any function from the package there's an error because pixiv changed their captcha to version 2 and that's not supported in the free version of cloudscraper
edit: to workaround and make everything work use set_auth(access_token, refresh_token) instead of api.auth
The text was updated successfully, but these errors were encountered: