Skip to content
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

Enhanced utils.py and webdriver.py #274

Merged
merged 15 commits into from
Jun 29, 2024
Merged

Conversation

dmytrokoren
Copy link
Contributor

@dmytrokoren dmytrokoren commented Jun 11, 2024

  1. Enhanced utils.py: Employed randomized timing for multiple attempts, mitigating 403 errors.
  2. Revamped webdriver.py: Incorporated random timing during login to prevent 429 errors.

Tested on:

  • Windows 11 docker, WSL2
  • Synology DSM 7.2 (Container Manager)
  • Mac OS docker, arm64
  • Mac OS native, arm64

NOTE: You have to be on your residential IP address (including docker), VPN will throw 403 on fare check!

…mitigating 403 errors.

Revamped webdriver.py: Incorporated random timing during login to prevent 429 errors.
@Bubba8291
Copy link

@dmytrokoren This replaces #268 right? And what's different about it?

@dmytrokoren
Copy link
Contributor Author

@dmytrokoren This replaces #268 right? And what's different about it?

@Bubba8291 No difference, just minor tweaks.

Copy link
Owner

@jdholtz jdholtz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding and testing with the random intervals. I unfortunately have still been receiving some 403s using your develop6 tag, but it has definitely improved over v7.5.

lib/utils.py Outdated Show resolved Hide resolved
lib/webdriver.py Outdated Show resolved Hide resolved
@dmytrokoren
Copy link
Contributor Author

Thanks for adding and testing with the random intervals. I unfortunately have still been receiving some 403s using your develop6 tag, but it has definitely improved over v7.5.

I haven't pushed the latest changes yet. These changes don't fix 403 yet. I will push latest tomorrow. Please check latest tag not develop6 (it's outdated) thanks @jdholtz

@dmytrokoren
Copy link
Contributor Author

Thanks for adding and testing with the random intervals. I unfortunately have still been receiving some 403s using your develop6 tag, but it has definitely improved over v7.5.

@jdholtz - please try :latest tag

@jdholtz
Copy link
Owner

jdholtz commented Jun 18, 2024

I've tried this on my machine, a Pi, and an Ubuntu server. They all work well. The only issue I'm running into is I'm occasionally getting the following error. It seems to happen more consistently on the Ubuntu server using Google Chrome instead of Chromium, but I did get it as well on the Pi for one run

seleniumbase.common.exceptions.ElementNotVisibleException: Message: 
 Element {(//button[contains(@class,'closeButton')])[2]} was not visible after 7 seconds!

I saw through screenshots that the popup did not appear, so I tried ignoring it. However, then the headers never were loaded. This PR is very close to fixing the issue, but I'm not exactly sure why this particular issue exists.

@dmytrokoren
Copy link
Contributor Author

I've tried this on my machine, a Pi, and an Ubuntu server. They all work well. The only issue I'm running into is I'm occasionally getting the following error. It seems to happen more consistently on the Ubuntu server using Google Chrome instead of Chromium, but I did get it as well on the Pi for one run


seleniumbase.common.exceptions.ElementNotVisibleException: Message: 

 Element {(//button[contains(@class,'closeButton')])[2]} was not visible after 7 seconds!

I saw through screenshots that the popup did not appear, so I tried ignoring it. However, then the headers never were loaded. This PR is very close to fixing the issue, but I'm not exactly sure why this particular issue exists.

That is awesome news! I will fix this issue tonight and push changes.

lib/reservation_monitor.py Show resolved Hide resolved
lib/reservation_monitor.py Outdated Show resolved Hide resolved
lib/utils.py Outdated Show resolved Hide resolved
lib/webdriver.py Show resolved Hide resolved
lib/webdriver.py Outdated Show resolved Hide resolved
lib/webdriver.py Outdated Show resolved Hide resolved
@dmytrokoren
Copy link
Contributor Author

@jdholtz check this tag :develop

@jdholtz
Copy link
Owner

jdholtz commented Jun 18, 2024

@jdholtz check this tag :develop

I just pulled this tag. However, I'm getting the following error when running it through Docker on my laptop. I think the last strategy worked well (the MY_ACCOUNT_URL), but we just need to figure why it isn't always loading. However, it may be because it is being detected which would mean a new strategy is needed.

selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <img alt="Check in banner" class="image-placement--background-image" height="51" src="/content/mkt/images/hero_shots/mobileSliver-CheckIn-test-20210330.png" width="390"> is not clickable at point (195, 280). Other element would receive the click: <h3 class="popup-title">...</h3>
  (Session info: chrome=125.0.6422.112)

There is another strategy that may be worth experimenting with which is running SeleniumBase with a virtual display: seleniumbase/SeleniumBase#2390 (comment). I believe I tried this a few months ago and it didn't work, but it's worth trying again in case I didn't do it correctly or a SB update improved it.

In my opinion, the best way to fix 403s is to find out why they are happening on headless environments (docker, ubuntu server, etc.), for the most part, but not happening on devices with displays. I've spent a lot of time since the issue started to try and find out why but have not been successful yet.

@dmytrokoren
Copy link
Contributor Author

@jdholtz check this tag :develop

I just pulled this tag. However, I'm getting the following error when running it through Docker on my laptop. I think the last strategy worked well (the MY_ACCOUNT_URL), but we just need to figure why it isn't always loading. However, it may be because it is being detected which would mean a new strategy is needed.


selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <img alt="Check in banner" class="image-placement--background-image" height="51" src="/content/mkt/images/hero_shots/mobileSliver-CheckIn-test-20210330.png" width="390"> is not clickable at point (195, 280). Other element would receive the click: <h3 class="popup-title">...</h3>

  (Session info: chrome=125.0.6422.112)

There is another strategy that may be worth experimenting with which is running SeleniumBase with a virtual display: seleniumbase/SeleniumBase#2390 (comment). I believe I tried this a few months ago and it didn't work, but it's worth trying again in case I didn't do it correctly or a SB update improved it.

In my opinion, the best way to fix 403s is to find out why they are happening on headless environments (docker, ubuntu server, etc.), for the most part, but not happening on devices with displays. I've spent a lot of time since the issue started to try and find out why but have not been successful yet.

That's so weird. It worked on my docker Mac m1. I will need to use js_click that will avoid this error. I'll fix it again tonight :)

@dmytrokoren
Copy link
Contributor Author

I will check to see if we can utilize the virtual desktop but I did start to poke at this but like you said unsuccessful :/

@dmytrokoren
Copy link
Contributor Author

@jdholtz check this tag :develop

I just pulled this tag. However, I'm getting the following error when running it through Docker on my laptop. I think the last strategy worked well (the MY_ACCOUNT_URL), but we just need to figure why it isn't always loading. However, it may be because it is being detected which would mean a new strategy is needed.

selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <img alt="Check in banner" class="image-placement--background-image" height="51" src="/content/mkt/images/hero_shots/mobileSliver-CheckIn-test-20210330.png" width="390"> is not clickable at point (195, 280). Other element would receive the click: <h3 class="popup-title">...</h3>
  (Session info: chrome=125.0.6422.112)

There is another strategy that may be worth experimenting with which is running SeleniumBase with a virtual display: seleniumbase/SeleniumBase#2390 (comment). I believe I tried this a few months ago and it didn't work, but it's worth trying again in case I didn't do it correctly or a SB update improved it.

In my opinion, the best way to fix 403s is to find out why they are happening on headless environments (docker, ubuntu server, etc.), for the most part, but not happening on devices with displays. I've spent a lot of time since the issue started to try and find out why but have not been successful yet.

I have tried the virtual display (sbvirtualdisplay) it's not working for me, I received 429 error on login. The real issue here is user-agent it's detecting somehow. If we set is_mobile=False in virtual display it will fail fare check every time and login session with 429 error intermittently. Right now is_mobile=True it's working, with proper workarounds. No need virtual display.

@Bubba8291
Copy link

@dmytrokoren How often are the errors now with your branch? I told my cousin I would get her a good boarding position on Friday. But I assured her that it's not guaranteed.

I am also suitable to run it on a stable residential internet, so no VPS.

@dmytrokoren
Copy link
Contributor Author

@dmytrokoren How often are the errors now with your branch? I told my cousin I would get her a good boarding position on Friday. But I assured her that it's not guaranteed.

I am also suitable to run it on a stable residential internet, so no VPS.

@Bubba8291 try this tag (develop) https://hub.docker.com/r/dmytrokoren/auto-southwest-check-in/

I'm running it without any issues on fare check or scheduled check in. It's been stable for me at least. Give it a go and report back here.

@Bubba8291
Copy link

@dmytrokoren How often are the errors now with your branch? I told my cousin I would get her a good boarding position on Friday. But I assured her that it's not guaranteed.
I am also suitable to run it on a stable residential internet, so no VPS.

@Bubba8291 try this tag (develop) https://hub.docker.com/r/dmytrokoren/auto-southwest-check-in/

I'm running it without any issues on fare check or scheduled check in. It's been stable for me at least. Give it a go and report back here.

@dmytrokoren I do not use Docker. If I fetch and pull dmytrokoren/auto-southwest-check-in:master, it's the same commits as your latest Docker develop tag, right?

@dmytrokoren
Copy link
Contributor Author

@dmytrokoren I do not use Docker. If I fetch and pull dmytrokoren/auto-southwest-check-in:master, it's the same commits as your latest Docker develop tag, right?

If using desktop, I'm not sure if it works on Windows platform. On Mac it works but make sure it does not go to sleep.

First, download the script onto your computer

git clone https://github.com/dmytrokoren/auto-southwest-check-in.git

@Bubba8291
Copy link

@dmytrokoren I do not use Docker. If I fetch and pull dmytrokoren/auto-southwest-check-in:master, it's the same commits as your latest Docker develop tag, right?

If using desktop, I'm not sure if it works on Windows platform. On Mac it works but make sure it does not go to sleep.

First, download the script onto your computer

git clone https://github.com/dmytrokoren/auto-southwest-check-in.git

Yep. Thank you. I already have it setup on a headless machine. I just wanted to make sure your docker tag was the same as your latest GitHub branch.

@dmytrokoren
Copy link
Contributor Author

Yep. Thank you. I already have it setup on a headless machine. I just wanted to make sure your docker tag was the same as your latest GitHub branch.

Yup it is. Keep us posted how it checks in )

@jdholtz jdholtz mentioned this pull request Jun 21, 2024
@jdholtz
Copy link
Owner

jdholtz commented Jun 21, 2024

The only issue I was getting was a 403 when it was fetching the reservation information within the checkin scheduler. What fixed it for me (I'm not 100% confident because I don't think I got another failed attempt) is to add is_fare_checker=True to the make_request call in the _get_reservation_info function.

I'll probably change it to default to making random delays between requests and turn it off within the checkin handler, but you don't need to worry about doing that for this PR.

Reverted to original state
@dmytrokoren
Copy link
Contributor Author

This is a great PR, it brings the script back to full functionality. Thanks for all of your hard work on this!

I'm glad to help. This is a great project and it is fun to work on.

@Bubba8291
Copy link

@dmytrokoren I would like to double check since it's not in the README yet. Which browser is better for your fork using headless Ubuntu Focal (20.04)? Google chrome or Chromium?

@Bubba8291
Copy link

@dmytrokoren Good news kind of. My cousin got A46. But it took 10 attempts to be successful. I think she might've gotten lucky since it took 14 extra seconds.

2024-06-21 14:09:55 DEBUG Process-1:1[checkin_handler:188]: Making GET request to check in
2024-06-21 14:09:56 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 1 attempts
2024-06-21 14:09:58 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 2 attempts
2024-06-21 14:09:59 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 3 attempts
2024-06-21 14:10:00 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 4 attempts
2024-06-21 14:10:01 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 5 attempts
2024-06-21 14:10:02 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 6 attempts
2024-06-21 14:10:02 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 7 attempts
2024-06-21 14:10:07 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 8 attempts
2024-06-21 14:10:12 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 9 attempts
2024-06-21 14:10:14 DEBUG Process-1:1[utils:47]: Successfully made request after 10 attempts
2024-06-21 14:10:14 DEBUG Process-1:1[checkin_handler:194]: Making POST request to check in
2024-06-21 14:10:16 DEBUG Process-1:1[utils:47]: Successfully made request after 1 attempts
2024-06-21 14:10:16 DEBUG Process-1:1[checkin_handler:165]: Successfully checked in after 1 attempts
2024-06-21 14:10:16 DEBUG Process-1:1[notification_handler:105]: Sending successful check-in notification...```

@dmytrokoren
Copy link
Contributor Author

dmytrokoren commented Jun 21, 2024

@Bubba8291 A46 is good, considering people pay for A15-A30 early bird. Regarding GET request was attempting multiple times, I think SW api was not responsive at that time as there is no 403 error. At this point there is very little that can be done related to this. My environment just like yours DSM, is working good right now with everything one attempt. I'm yet to try check-in, I have a trip coming up in mid July, I can report back how my check-in went.

@dmytrokoren
Copy link
Contributor Author

@dmytrokoren I would like to double check since it's not in the README yet. Which browser is better for your fork using headless Ubuntu Focal (20.04)? Google chrome or Chromium?

I'm using Chromium headless. How it is setup in docker file, nothing changed.

Added random_sleep into two areas to avoid bot detection
@dmytrokoren
Copy link
Contributor Author

dmytrokoren commented Jun 22, 2024

The only issue I was getting was a 403 when it was fetching the reservation information within the checkin scheduler. What fixed it for me (I'm not 100% confident because I don't think I got another failed attempt) is to add is_fare_checker=True to the make_request call in the _get_reservation_info function.

I'll probably change it to default to making random delays between requests and turn it off within the checkin handler, but you don't need to worry about doing that for this PR.

Added the random_sleep (prev aka is_fare_checker) to _get_reservation_info in checkin_scheduler.

@dmytrokoren Good news kind of. My cousin got A46. But it took 10 attempts to be successful. I think she might've gotten lucky since it took 14 extra seconds.

2024-06-21 14:09:55 DEBUG Process-1:1[checkin_handler:188]: Making GET request to check in
2024-06-21 14:09:56 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 1 attempts
2024-06-21 14:09:58 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 2 attempts
2024-06-21 14:09:59 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 3 attempts
2024-06-21 14:10:00 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 4 attempts
2024-06-21 14:10:01 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 5 attempts
2024-06-21 14:10:02 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 6 attempts
2024-06-21 14:10:02 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 7 attempts
2024-06-21 14:10:07 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 8 attempts
2024-06-21 14:10:12 DEBUG Process-1:1[utils:64]: Sleeping for 0.50 seconds after 9 attempts
2024-06-21 14:10:14 DEBUG Process-1:1[utils:47]: Successfully made request after 10 attempts
2024-06-21 14:10:14 DEBUG Process-1:1[checkin_handler:194]: Making POST request to check in
2024-06-21 14:10:16 DEBUG Process-1:1[utils:47]: Successfully made request after 1 attempts
2024-06-21 14:10:16 DEBUG Process-1:1[checkin_handler:165]: Successfully checked in after 1 attempts
2024-06-21 14:10:16 DEBUG Process-1:1[notification_handler:105]: Sending successful check-in notification...```

@jdholtz also added random_sleep to make_request in [checkin_handler: line 188] the reason is that @Bubba8291 had some api request issue and it only went through after 10 attempts.

btw random_sleep I have made a change instead of (1, 6) it is now (1, 3) so it does not have a high delay time.

Copy link
Owner

@jdholtz jdholtz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple of small things before I merge this. Don’t worry about adding tests (the workflow will fail when I accept it). I’ll add them after the merge.

lib/utils.py Outdated Show resolved Hide resolved
lib/checkin_handler.py Show resolved Hide resolved
@dmytrokoren dmytrokoren requested a review from jdholtz June 26, 2024 07:12
@jdholtz
Copy link
Owner

jdholtz commented Jun 26, 2024

@dmytrokoren the linting/formatting workflow is failing. Could you fix those issues before I merge?

As a tip, I recommend using pre-commit (details are in the developers doc) so the formatters automatically run and fix it for you.

@dmytrokoren
Copy link
Contributor Author

@dmytrokoren the linting/formatting workflow is failing. Could you fix those issues before I merge?

As a tip, I recommend using pre-commit (details are in the developers doc) so the formatters automatically run and fix it for you.

Done with pre-commit

black....................................................................Passed
codespell................................................................Passed
flake8...................................................................Passed
isort....................................................................Passed

@bradzab0623
Copy link

@jdholtz @dmytrokoren I've started using this version and it does seem pretty good. One thing I did notice is when trying to log in or check fares for many accounts and/or reservations at once, I get errors again after the first couple. Can we stagger the log ins and fare checks when running the script against many accounts and/or reservations? I understand we can't do that with the actual check ins.

@jdholtz
Copy link
Owner

jdholtz commented Jun 28, 2024

Can we stagger the log ins and fare checks when running the script against many accounts and/or reservations?

Yeah, it may work better if there was a stagger between each account/reservation. Because the script sleeps for exactly 24 hours (or whatever retrieval interval is set), this only needs to be implemented when each process is started as the times between each will stay consistent throughout the script's running time.

@dmytrokoren I have also been starting to see 403s with just one account and 2 reservations again. Very confused what could've changed...

@dmytrokoren
Copy link
Contributor Author

Can we stagger the log ins and fare checks when running the script against many accounts and/or reservations?

Yeah, it may work better if there was a stagger between each account/reservation. Because the script sleeps for exactly 24 hours (or whatever retrieval interval is set), this only needs to be implemented when each process is started as the times between each will stay consistent throughout the script's running time.

@dmytrokoren I have also been starting to see 403s with just one account and 2 reservations again. Very confused what could've changed...

@jdholtz I've been running 4 accounts / 0 reservations for 4 days now in docker (synology). Not one single 403/429 error (fingers crossed) - fare checks and header refresh working flawlessly. That's why im confused why its happening to other people?!

@@ -87,8 +87,8 @@ def set_up_check_in(arguments: List[str]) -> None:
logger.error("Invalid arguments. For more information, try '--help'")
sys.exit(2)

logger.debug(
"Monitoring %d accounts and %d reservations", len(config.accounts), len(config.reservations)
print(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to use print instead of logger.debug?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was meant to be print. It's helpful for debugging though so I'll make it a logger.info.

@dmytrokoren
Copy link
Contributor Author

@jdholtz is the PR going to be merged?

@jdholtz jdholtz merged commit effeac7 into jdholtz:develop Jun 29, 2024
4 of 19 checks passed
@jdholtz
Copy link
Owner

jdholtz commented Jun 29, 2024

Yes, just did @dmytrokoren. Thanks!

@natecodes
Copy link
Contributor

2024-07-01 12:12:44 DEBUG MainProcess[log:24]: Initialized the application
2024-07-01 12:12:44 DEBUG MainProcess[main:113]: Auto-Southwest Check-In v7.5
2024-07-01 12:12:44 DEBUG MainProcess[main:71]: Called with 0 arguments
2024-07-01 12:12:44 DEBUG MainProcess[config:132]: Initializing configuration file
2024-07-01 12:12:44 DEBUG MainProcess[config:161]: Reading the configuration file
2024-07-01 12:12:44 DEBUG MainProcess[config:174]: Reading configuration from environment variables
2024-07-01 12:12:44 DEBUG MainProcess[config:60]: Setting check fares to True
2024-07-01 12:12:44 DEBUG MainProcess[config:75]: Setting retrieval interval to 24 hours
2024-07-01 12:12:44 DEBUG MainProcess[config:109]: Setting notification level to <NotificationLevel.INFO: 1>
2024-07-01 12:12:44 DEBUG MainProcess[config:122]: Using 0 notification services
2024-07-01 12:12:44 DEBUG MainProcess[config:144]: Creating configurations for 1 accounts
2024-07-01 12:12:44 DEBUG MainProcess[config:151]: Creating configurations for 0 reservations
2024-07-01 12:12:44 INFO MainProcess[main:97]: Monitoring 1 account and 0 reservations

2024-07-01 12:12:44 DEBUG Process-1[reservation_monitor:168]: Acquiring lock...
2024-07-01 12:12:44 DEBUG Process-1[reservation_monitor:170]: Lock acquired
2024-07-01 12:12:44 DEBUG Process-1[reservation_monitor:192]: Retrieving reservations for account
2024-07-01 12:12:44 DEBUG Process-1[webdriver:126]: Starting webdriver for current session
2024-07-01 12:12:45 DEBUG Process-1[webdriver:143]: Using browser version: 126.0.6478.127
2024-07-01 12:12:45 DEBUG Process-1[webdriver:147]: Loading Southwest home page (this may take a moment)
2024-07-01 12:12:52 DEBUG Process-1[webdriver:100]: Logging into account to get a list of reservations and valid headers
2024-07-01 12:12:54 DEBUG Process-1[webdriver:177]: Waiting for headers_set to be set
2024-07-01 12:12:54 DEBUG Process-1[webdriver:181]: headers_set set successfully
2024-07-01 12:12:55 DEBUG Process-1[webdriver:177]: Waiting for login_request_id to be set
2024-07-01 12:12:55 DEBUG Process-1[webdriver:169]: Login response has been received
2024-07-01 12:12:56 DEBUG Process-1[webdriver:181]: login_request_id set successfully
2024-07-01 12:12:56 DEBUG Process-1[webdriver:237]: Logging in failed for an unknown reason
2024-07-01 12:12:56 WARNING Process-1[reservation_monitor:201]: Encountered a Too Many Requests error while logging in. Skipping reservation retrieval
2024-07-01 12:12:56 DEBUG Process-1[reservation_monitor:181]: Lock released
2024-07-01 12:12:56 DEBUG Process-1[reservation_monitor:130]: Sleeping for 86387 seconds
^C2024-07-01 12:12:58 INFO MainProcess[main:122]:
Ctrl+C pressed. Stopping all check-ins

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants