So I'm learning my way around web crawlers and automatization. I'm trying to automate the login for mega.nz without using their official API (as far as I'm concerned it's even outdated for Python).
And this one is the code (currently not working since no data is really being sent). I don't want to use a browser.
loginURL = 'https://mega.nz/login'
requestURL = 'https://mega.nz/fm/dashboard'
payload = {
'login-name2': 'test#email.com',
'login-password2': 'password',
'login-check2': ''
}
with requests.session() as s:
s.post(loginURL, headers=headers, data=payload)
r = s.get(requestURL)
print(r.text)
Headers I am using:
{'Content-Type': 'text/html', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'MEGA-Chrome-Antileak', 'Access-Control-Max-Age': '86400', 'Content-Encoding': 'gzip', 'Content-Length': '934', 'Strict-Transport-Security': 'max-age=63072000; includeSubDomains; preload', 'X-Frame-Options': 'DENY', 'Set-Cookie': 'geoip=IT', 'Content-Security-Policy': "default-src 'self' data: blob: *.mega.co.nz *.mega.nz http://*.mega.co.nz http://*.mega.nz wss://*.karere.mega.nz *.karere.mega.nz:1380 http://127.0.0.1:6341 localhost.megasyncloopback.mega.nz:6342; script-src 'self' *.mega.co.nz *.mega.nz data: blob:; style-src 'self' 'unsafe-inline' *.mega.co.nz *.mega.nz data: blob:; frame-src 'self' mega: *.megaad.nz; img-src 'self' *.mega.co.nz *.mega.nz data: blob:", 'Connection': 'Keep-Alive'}
How can I automate signing into this?
Try this https://github.com/richardARPANET/mega.py/
It worked for me.
There is an example step by step on README.rst
You may want to read requests documentation about Authentication, it gives a few methods to authenticate through HTTP.
You can find it here.
I did not find any information about an HTTP API for Mega. Are you trying to get access to the site via the web interface that you would use in your browser? It could be very difficult or impossible to get your software working this way.
Usually you would only use plain HTTP requests when the service you try to access provides a working REST API. (see for example the Spotify API)
Maybe take a look at this example for accessing Mega from Python. This uses the official Mega C++ API which you can access from your Python script.
Related
I have an API I am building out that will allow me to upload media to my WordPress website using their new API. I have searched all over the internet and SO for a solution to this problem, but all of the answers seem to be using an older WordPress API so I have not had much success in finding an answer.
I have the following code written out in a function to send a multipart/form-data request to the API:
img = open(image_path, 'rb')
file_name = os.path.basename(image)
print('Compressing and sending data...')
NEW_HEADER = {
'Authorization': f'BEARER {WORDPRESS_ACCESS_TOKEN}',
'Content-Disposition': f'attachment; filename={file_name}',
'Content-Type': 'multipart/form-data'
}
response = requests.post(
url=WORDPRESS_MEDIA_URL,
files={'media': img.read()},
headers=NEW_HEADER
)
print(response.request)
print(response.text)
return response
Which returns me:
{"media":[],"errors":[]}
<Response [200]>
OK
So, it sends something to the endpoint, but it's return an empty array and empty error box. Again, I can't seem to find any solution for the new WP, so forgive me if the Python seems a little hacky and put-together, I've just been putting together what appears to work.
Further Reading Since Original Posting
I pinged the API with Postman and it returns data as expected:
{"media":[{"id":"xxxx","date":"2022-11-03T20:06:54-05:00","parent":0,"link":"https:mywebsite","title":"mypicture","caption":"","description":"",...}
So, Since the post request seems to not be the issue, I tried to debug my request in Postman and my local console to see what was being sent:
{'User-Agent': 'python-requests/2.28.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Authorization': 'BEARER QnkXS43KhiqO7Oa!9G!zN2gnz90hHhZEribF2ddZu0h8&5V0p5M69^OwDb9E6H%B', 'Content-Type': 'multipart/form-data', 'Content-Length': '6'}
media=
And I see that the media returns empty from my local console. In Postman, the media is returned as undefined (though I'm not sure if that's just Postman being unable to parse the image in a JSON format in the console/debugger.
This leads me to believe that either the way I am accessing/calling the directory with the image is wrong, or the way I am trying to encode it to the request.
Even Further Reading Since Posting
I have since circumnavigated any concerns about directory issues by copying the photos from an external directory to that of one inside the project folder.
Since then, it appears that the current way I am sending the data returns the same response as if I am sending nothing at all:
response = requests.post(
url=WORDPRESS_MEDIA_URL, # there is no data sent in this request.
headers=NEW_HEADER
)
Which still returns me:
{"media":[],"errors":[]}
<Response [200]>
OK
This leads me to believe that the way I am sending the data is incorrect, as WordPress is receiving my request, but is not getting the information that it needs.
So, doing some further reading and research, I come across requests-toolbelt, which is to help sending multipart/form-data:
data = MultipartEncoder(fields={'media': (file_name, img, 'image/jpeg')})
new_header = {
'Authorization': f'BEARER {WORDPRESS_ACCESS_TOKEN}',
'Content-Type': data.content_type,
'Content-Disposition': 'form-data; name="media"; filename="%s"' % name_img,
}
response = requests.post(WORDPRESS_MEDIA_URL, data=data, headers=new_header)
Now, when I send a request with this data, I get this response:
{"error":"unsupported_mime_type","message":"File type unknown"}
<Response [400]>
Bad Request
So sending the request with the MultipartEncoder returns an error of an unsupported MIME type. So while it isn't a blank 200 response, it gives me reason to think that perhaps I am using the MultipartEncoder wrong, or I am not making the proper adjustments to the picture I am trying to upload.
Any insight into this would be greatly appreciated.
I'd like to call the openshift machine api (/apis/machine.openshift.io/v1beta1/machines). Is there a way to do this using the kubernetes Python module? I can create an api object like this:
>>> from kubernetes import client, config
>>> config.load_incluster_config()
>>> api = client.CoreV1API()
Of course, that's a core API client, which doesn't include native support for the machine api. But the object has all the endpoint and authentication information. There is a likely looking api.api_client.call_api method, but it doesn't seem to make use of the auth information embedded in the api_client object:
>>> api.api_client.call_api('/apis/machine.openshift.io/v1beta1/machines', 'GET')
[...]
kubernetes.client.rest.ApiException: (403)
Reason: Forbidden
I can explicitly pass in auth information, but then it doesn't seem to return any content:
>>> >>> api.api_client.call_api('/apis/machine.openshift.io/v1beta1/machines', 'GET', auth_settings=api.api_client.configuration.auth_settings())
(None, 200, HTTPHeaderDict({'Audit-Id': '6f6965b5-1ad7-4c5e-ab61-343e38718ff8', 'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'X-Kubernetes-Pf-Flowschema-Uid': '9
5848e47-b51c-46eb-aa4f-e25130d61e09', 'X-Kubernetes-Pf-Prioritylevel-Uid': '39391d77-7b32-4aa2-93c3-9915a302d361', 'Date': 'Fri, 04 Sep 2020 19:43:59 GMT', 'Transfer-Encoding': 'chunked'}))
I can of course just use requests:
>>> requests.get(f'{api.api_client.configuration.host}/apis/machine.openshift.io/v1beta1/machines', verify=False, headers=api.api_client.configuration.api_key)
<Response [200]>
That works fine, but it smells like I'm going about things the wrong way. What's the correct way to make arbitrary API requests using the Python kubernetes module?
Referring from here you could use api_client.call_api as below to call arbitrary APIs by passing a valid BearerToken which could be a service account token.
api_client.call_api('/apis/machine.openshift.io/v1beta1/machines', 'GET', auth_settings = ['BearerToken'], response_type='json', _preload_content=False)
I'm trying to get the oauth request_token for Twitter as described here, making a call to "oauth/request_token": https://dev.twitter.com/docs/auth/implementing-sign-twitter
I'm generating the params using the encode_params function in here: https://github.com/sixohsix/twitter/blob/master/twitter/oauth.py
I then wrap the returned string in a dict with they key "Authorization" and dump it into the Headers of the Post request I'm making using the python request library. Here's the two lines I use to create the request.
ep = "OAuth " + auth.encode_params(baseUrl, method, params)
response = requests.post(baseUrl+method, headers={ "Authorization" : ep})
The eventual header looks like this (consumer_key modified):
{'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate, compress',
'Authorization': 'OAuth oauth_callback=http%253A%252F%252Fec2-54-244-189-248.us-west-2.compute.amazonaws.com%252Fct%252Ftwitter_login_handler%252F&oauth_consumer_key=xxx&oauth_nonce=14937468581358710045&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1366568033&oauth_version=1.0&oauth_signature=kiYucZzPY%2FXy2WyJliJ6YcggVzQ%3D',
'Content-Length': '0',
'User-Agent': 'python-requests/1.2.0 CPython/2.7.3 Linux/3.5.0-21-generic'}
However, I'm still getting a 401 response that says: 'Failed to validate oauth signature and token'
Any idea what I'm doing wrong? Any help would really be appreciated.
I can't speak to the script you reference, but if you're willing to try another library as the author of rauth I can recommend it. Here's a working Twitter example. Hope that helps.
I ended up using python-oauth2. Their instructions were a little out of date, so I updated them and submitted a pull request. As of right now, it's not been accepted, but here's a link to the forked repo with the updated instructions.
Hopefully this helps someone else...
From the code referenced by maxcountryman - it has a comment that I had not found elsewhere till then :
# Get a real consumer key & secret from https://dev.twitter.com/apps/new
That helped me progress a lot...
Cheers, Ian
.
When I access a page on an IIS server to retrieve xml, using a query parameter through the browser (using the http in the below example) I get a pop-up login dialog for username and password (appears to be a system standard dialog/form). and once submitted the data arrives. as an xml page.
How do I handle this with urllib? when I do the following, I never get prompted for a uid/psw.. I just get a traceback indicating the server (correctly ) id's me as not authorized. Using python 2.7 in Ipython notebook
f = urllib.urlopen("http://www.nalmls.com/SERetsHuntsville/Search.aspx?SearchType=Property&Class=RES&StandardNames=0&Format=COMPACT&Query=(DATE_MODIFIED=2012-09-28T00:00:00%2B)&Limit=10")
s = f.read()
f.close()
Pointers to doc also appreciated! did not find this exact use case.
I plan to parse the xml to csv if that makes a difference.
You are dealing with http authentication. I've always found it tricky to get working quickly with the urllib library. The requests python package makes it super simple.
url = "http://www.nalmls.com/SERetsHuntsville/Search.aspx?SearchType=Property&Class=RES&StandardNames=0&Format=COMPACT&Query=(DATE_MODIFIED=2012-09-28T00:00:00%2B)&Limit=10"
r = requests.get(url, auth=('user', 'pass'))
page = r.text
If you look at the headers for that url you can see that it is using digest authentication:
{'content-length': '1893', 'x-powered-by': 'ASP.NET',
'x-aspnet-version': '4.0.30319', 'server': 'Microsoft-IIS/7.5',
'cache-control': 'private', 'date': 'Fri, 05 Oct 2012 18:20:54 GMT',
'content-type': 'text/html; charset=utf-8', 'www-authenticate':
'Digest realm="Solid Earth", nonce="MTAvNS8yMDEyIDE6MjE6MjUgUE0",
opaque="0000000000000000", stale=false, algorithm=MD5, qop="auth"'}
So you will need:
from requests.auth import HTTPDigestAuth
r = requests.get(url, auth=HTTPDigestAuth('user', 'pass'))
There are many ways to do it but i suggest you start with urllib2 and it's batteries included.
import urllib2, base64
req = urllib2.Request("http://webpage.com//user")
b64str = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
request.add_header("Authorization", "Basic %s" % b64str)
result = urllib2.urlopen(req)
You can use requests, beautifulsoup,mechanize or selenium if your task gets harder. Googling will give you enough examples for each one of these,
This can be done in a couple of ways:
Use urllib/urllib2 and requests as others have suggested
Use Mechanize to simulate manual form-filling and get back the response
I am trying to get my Django app (NOT using Google app engine) retrieve data from Google Contacts using Google Contacts Data API. Going through authentication documentation as well as Data API Python client docs
First step (AuthSubRequest) which is getting the single-use token works fine. The next step(AuthSubSessionToken), which is upgrade single-use token to a session token. The python API call UpgradeToSessionToken() simply didn't work for me it gave me NonAuthSubToken exception:
gd_client = gdata.contacts.service.ContactsService()
gd_client.auth_token = authsub_token
gd_client.UpgradeToSessionToken()
As an alternative I want to get it working by "manually" constructing the HTTP request:
url = 'https://www.google.com/accounts/AuthSubSessionToken'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'AuthSub token=' + authsub_token,
'User-Agent': 'Python/2.6.1',
'Host': 'https://www.google.com',
'Accept': 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2',
'Connection': 'keep-alive',
}
req = urllib2.Request(url, None, headers)
response = urllib2.urlopen(req)
this gives me a different error:
HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop. The last 30x error message was: Moved Temporarily
What am I doing wrong here? I'd appreciate help/advice/suggestions with either of the methods I am trying to use: Python API call (UpgradeToSessionToken) or manually constructing HTTP request with urllib2.
According to the 2.0 documentation here there is a python example set...
Running the sample code
A full working sample client, containing all the sample code shown in this document, is available in the Python client library distribution, under the directory samples/contacts/contacts_example.py.
The sample client performs several operations on contacts to demonstrate the use of the Contacts Data API.
Hopefully it will point you in the right direction.
I had a similar issue recently. Mine got fixed by setting "secure" to "true".
next = 'http://www.coolcalendarsite.com/welcome.pyc'
scope = 'http://www.google.com/calendar/feeds/'
secure = True
session = True
calendar_service = gdata.calendar.service.CalendarService()
There are four different ways to authenticate. Is it really that important for you to use AuthSub? If you can't get AuthSub to work, then consider the ClientLogin approach. I had no trouble getting that to work.