@@ -135,46 +135,65 @@ def _get_context(self, element: Any) -> Union[Page, FrameLocator]:
135135
136136 return context
137137
138- async def scroll_to_bottom (self , timeout : float = 30000 ) -> None :
138+ async def scroll_to_bottom (
139+ self ,
140+ timeout : float = 30000 ,
141+ scroll_increment : int = 1000 ,
142+ no_progress_limit : int = 3 ,
143+ ) -> None :
139144 """
140- Scrolls to the bottom of the page continuously until the bottom is reached or a timeout occurs.
141-
142- This method scrolls the page in increments of 1000 pixels, checking the scroll position
143- and resetting the timeout if progress is made. It stops scrolling once the bottom is reached
144- or if the specified timeout is exceeded.
145+ Scrolls to the bottom of the page until no more progress is made or a timeout occurs.
145146
146147 Args:
147148 timeout (float, optional): The maximum amount of time (in milliseconds) to continue scrolling. Defaults to 30000.
149+ scroll_increment (int, optional): The number of pixels to scroll in each step. Defaults to 1000.
150+ no_progress_limit (int, optional): The number of consecutive attempts with no progress before stopping. Defaults to 3.
148151
149152 Returns:
150153 None
151154 """
152- i = 0
153- last_scroll_position = 0
154155 start_time = time .time ()
156+ last_scroll_position = 0
157+ no_progress_count = 0
155158
156159 while True :
157160 current_scroll_position = await self .playwright_page .evaluate (
158161 "window.scrollY"
159162 )
163+ scroll_height = await self .playwright_page .evaluate (
164+ "document.body.scrollHeight"
165+ )
160166
161- await self .playwright_page .evaluate (f"window.scrollTo(0, { i } )" )
162- i += 1000
167+ # Scroll down
168+ await self .playwright_page .evaluate (
169+ f"window.scrollTo(0, { current_scroll_position + scroll_increment } )"
170+ )
163171
164- if time .time () - start_time > timeout * 0.001 :
172+ # Check if we've reached the bottom
173+ if (
174+ self .playwright_page .viewport_size
175+ and current_scroll_position
176+ + self .playwright_page .viewport_size ["height" ]
177+ >= scroll_height
178+ ):
165179 break
166180
167- if current_scroll_position - last_scroll_position > 1000 :
168- start_time = time .time ()
181+ # Check if we've made progress
182+ if current_scroll_position > last_scroll_position :
183+ no_progress_count = 0
184+ else :
185+ no_progress_count += 1
169186
170- last_scroll_position = current_scroll_position
187+ # Stop if we haven't made progress for several attempts
188+ if no_progress_count >= no_progress_limit :
189+ break
171190
172- # # Check if the timeout has been exceeded
173- # if time.time() - start_time > timeout * 0.001:
174- # logger.debug("Timeout exceeded. Stopping scrolling.")
175- # break
191+ # Check if we've exceeded the timeout
192+ if time .time () - start_time > timeout * 0.001 :
193+ break
176194
177- logger .debug ("Done scrolling to the bottom of the page." )
195+ last_scroll_position = current_scroll_position
196+ await asyncio .sleep (0.1 )
178197
179198 async def close (self ) -> None :
180199 """
0 commit comments