lolokraus / DegiroAPI

An unofficial API for the trading platform Degiro, with the ability to get real time data and historical data
MIT License
215 stars 84 forks source link

Login isses due to Degiro's bot detection #61

Open petrklus opened 1 year ago

petrklus commented 1 year ago

I have started experiencing a "Could not login" error, with the response from the server reading:

         <h2>Reference: CENSORED</h2>
         <h2>Remote IP: CENSORED</h2>
         <h2>Identifier: CENSORED=python_bot</h2>
         <h2>Date: 07/Dec/2022:11:42:43 +0100</h2>
Jakub-CZ commented 1 year ago

56, #57, #58, #59, #60

petrklus commented 1 year ago

@Jakub-CZ I managed to work around the issue by setting user-agent headers:

headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}

This is my complete __request method hotfix:

    @staticmethod
    def __request(url, cookie=None, payload=None, headers=None, data=None, post_params=None, request_type=__GET_REQUEST,
                  error_message='An error occurred.'):

        headers_def = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
        if headers:
            headers = dict(list(headers_def.items()) + list(headers.items()))
        else:
            headers = headers_def

        if request_type == DeGiro.__DELETE_REQUEST:
            response = requests.delete(url, json=payload, headers=headers)
        elif request_type == DeGiro.__GET_REQUEST and cookie:
            response = requests.get(url, cookies=cookie, headers=headers)
        elif request_type == DeGiro.__GET_REQUEST:
            response = requests.get(url, params=payload, headers=headers)
        elif request_type == DeGiro.__POST_REQUEST and headers and data:
            response = requests.post(url, headers=headers, params=payload, data=data)
        elif request_type == DeGiro.__POST_REQUEST and post_params:
            response = requests.post(url, params=post_params, json=payload, headers=headers)
        elif request_type == DeGiro.__POST_REQUEST:
            response = requests.post(url, json=payload, headers=headers)
        else:
            raise Exception(f'Unknown request type: {request_type}')

        if response.status_code == 200 or response.status_code == 201:
            try:
                return response.json()
            except:
                return "No data"
        else:
            raise Exception(f'{error_message} Response: {response.text}')
petrklus commented 1 year ago

@Jakub-CZ curious, what is the workflow? why are the issues being closed when they are not actually being fixed on this repo? My understanding is that an issue is closed when it's fixed - that probably explains the number of people opening the issue, why would anyone look at closed issues to check for an active problem?

I would wager that issue should remain open unless there is a fix in the repo, which in this case there is not

Jakub-CZ commented 1 year ago

Fair point. Maybe we should've left one of those issues open so that people notice it more easily.

(Personally, I always search through closed issues as well. Often, an issue is closed when the corresponding PR is accepted, but it can take more time before all those changes get published.)


There's no workflow since the sole owner of this repo went silent. Nobody else can do anything here. Somebody else forked this repo, published a few new versions on PyPI, then they abandoned it as well.

You have two options:

  1. Switch to https://github.com/Chavithra/degiro-connector.
  2. If you don't want to rewrite your existing scripts, stick with this package (just install one of the patched versions).

I'm choosing No. 2, at least for now, since it's so easy to install Python packages from any commit.

petrklus commented 1 year ago

I will leave this one open then, to stand as a beacon to the other impatient who too do not look at the full complement of issues before creating another one 😂.

Thank you for the tips, I will check out the other one but considering the simplicity of the fix, I am happy to stick with this package as well.

Are you planning to maintain your fork is it only for your personal use?

Jakub-CZ commented 1 year ago

I plan to maintain my fork for the foreseeable future. But if Degiro change their API so much that it'd take too much effort to adapt to the change, I'll probably switch to another alternative at that point.

123m321 commented 1 year ago

How easy / difficult is it to connect with this api compared with the Chavi's api?

Jakub-CZ commented 1 year ago

I didn't try Chavi's library. Based on his docs it seems rather complex, just because it has so many functions and different modes of operation.

This library is the complete opposite - all the important code is in a single file; the other files only define the supplementary data classes. The code is fairly naive and trivial, the quality is on the low end. But thanks to that it's super easy to understand enough to make changes to it, if necessary. Of course, this wouldn't be relevant, had the library been well maintained, and worked out-of-box.

You might want to grab an example script from Chavi's repo and just give it a go. If it works for you, I'd go with that.

For me personally, this library is good enough since I only use it to pull my latest transactions, and push them to my spreadsheets. I could almost imagine using it for some simple Dollar Cost Averaging automation. But I wouldn't trust it enough to use it with a day-trading algorithm.

123m321 commented 1 year ago

I didn't try Chavi's library. Based on his docs it seems rather complex, just because it has so many functions and different modes of operation.

This library is the complete opposite - all the important code is in a single file; the other files only define the supplementary data classes. The code is fairly naive and trivial, the quality is on the low end. But thanks to that it's super easy to understand enough to make changes to it, if necessary. Of course, this wouldn't be relevant, had the library been well maintained, and worked out-of-box.

You might want to grab an example script from Chavi's repo and just give it a go. If it works for you, I'd go with that.

For me personally, this library is good enough since I only use it to pull my latest transactions, and push them to my spreadsheets. I could almost imagine using it for some simple Dollar Cost Averaging automation. But I wouldn't trust it enough to use it with a day-trading algorithm.

Thanks, I'm using an algo with Chavi's repo but somehow it ran into problems last week (after working flawless for a year). And I am puzzled why.

I don't need much from DeGiro, just the orderbook of prices and the ability to check and adjust my own orders.

The orderbook are the ten highest bid prices and then lowest ask prices in the market. The "real price" doesn't exist, only the last traded price exists in the market (and bids / offers).