@@ -135,46 +135,65 @@ def _get_context(self, element: Any) -> Union[Page, FrameLocator]:
135
135
136
136
return context
137
137
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 :
139
144
"""
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.
145
146
146
147
Args:
147
148
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.
148
151
149
152
Returns:
150
153
None
151
154
"""
152
- i = 0
153
- last_scroll_position = 0
154
155
start_time = time .time ()
156
+ last_scroll_position = 0
157
+ no_progress_count = 0
155
158
156
159
while True :
157
160
current_scroll_position = await self .playwright_page .evaluate (
158
161
"window.scrollY"
159
162
)
163
+ scroll_height = await self .playwright_page .evaluate (
164
+ "document.body.scrollHeight"
165
+ )
160
166
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
+ )
163
171
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
+ ):
165
179
break
166
180
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
169
186
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
171
190
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
176
194
177
- logger .debug ("Done scrolling to the bottom of the page." )
195
+ last_scroll_position = current_scroll_position
196
+ await asyncio .sleep (0.1 )
178
197
179
198
async def close (self ) -> None :
180
199
"""
0 commit comments