0
# Collection Operations
1
2
Playlist, channel, and search functionality for working with multiple YouTube videos, including bulk downloads and metadata extraction from video collections.
3
4
## Capabilities
5
6
### Playlist Class
7
8
Handle YouTube playlist operations for downloading and extracting metadata from multiple videos in a playlist.
9
10
```python { .api }
11
class Playlist:
12
def __init__(self, url: str, proxies: Optional[Dict[str, str]] = None):
13
"""
14
Initialize a Playlist object.
15
16
Args:
17
url (str): YouTube playlist URL
18
proxies (dict, optional): HTTP proxy configuration
19
"""
20
```
21
22
### Playlist Identification
23
24
Access playlist identification and URL properties.
25
26
```python { .api }
27
@property
28
def playlist_id(self) -> str:
29
"""Get the unique playlist identifier."""
30
31
@property
32
def playlist_url(self) -> str:
33
"""Get the full playlist URL."""
34
```
35
36
### Playlist Content Access
37
38
Access videos and URLs within the playlist.
39
40
```python { .api }
41
@property
42
def video_urls(self) -> DeferredGeneratorList:
43
"""
44
Get a list of video URLs in the playlist.
45
46
Returns:
47
DeferredGeneratorList: Lazy-loaded list of video URLs
48
"""
49
50
@property
51
def videos(self) -> Iterable[YouTube]:
52
"""
53
Get YouTube objects for each video in the playlist.
54
55
Returns:
56
Iterable[YouTube]: Iterator of YouTube objects
57
"""
58
59
def videos_generator(self) -> Iterator[YouTube]:
60
"""
61
Generator function that yields YouTube objects for playlist videos.
62
63
Returns:
64
Iterator[YouTube]: Generator yielding YouTube objects
65
"""
66
67
def url_generator(self) -> Iterator[str]:
68
"""
69
Generator function that yields video URLs from the playlist.
70
71
Returns:
72
Iterator[str]: Generator yielding video URLs
73
"""
74
```
75
76
### Playlist Metadata
77
78
Extract playlist information and statistics.
79
80
```python { .api }
81
@property
82
def title(self) -> Optional[str]:
83
"""Get the playlist title."""
84
85
@property
86
def description(self) -> str:
87
"""Get the playlist description."""
88
89
@property
90
def length(self) -> int:
91
"""Get the number of videos in the playlist."""
92
93
@property
94
def views(self) -> int:
95
"""Get the total playlist view count."""
96
97
@property
98
def last_updated(self) -> Optional[date]:
99
"""Get the last update date of the playlist."""
100
```
101
102
### Playlist Owner Information
103
104
Access information about the playlist creator.
105
106
```python { .api }
107
@property
108
def owner(self) -> str:
109
"""Get the playlist owner's name."""
110
111
@property
112
def owner_id(self) -> str:
113
"""Get the playlist owner's channel ID."""
114
115
@property
116
def owner_url(self) -> str:
117
"""Get the playlist owner's channel URL."""
118
```
119
120
### Playlist Navigation
121
122
Navigate and slice through playlist content.
123
124
```python { .api }
125
def trimmed(self, video_id: str) -> Iterable[str]:
126
"""
127
Get video URLs starting from a specific video ID.
128
129
Args:
130
video_id (str): Video ID to start from
131
132
Returns:
133
Iterable[str]: Video URLs from the specified point onward
134
"""
135
136
def __getitem__(self, i: Union[slice, int]) -> Union[str, List[str]]:
137
"""
138
Get video URL(s) by index or slice.
139
140
Args:
141
i (int or slice): Index or slice object
142
143
Returns:
144
str or List[str]: Video URL(s) at specified index/slice
145
"""
146
147
def __len__(self) -> int:
148
"""
149
Get the number of videos in the playlist.
150
151
Returns:
152
int: Number of videos
153
"""
154
```
155
156
### Playlist Technical Properties
157
158
Access technical information about the playlist.
159
160
```python { .api }
161
@property
162
def html(self) -> str:
163
"""Get the raw HTML content of the playlist page."""
164
165
@property
166
def ytcfg(self) -> dict:
167
"""Get the YouTube configuration data."""
168
169
@property
170
def initial_data(self) -> dict:
171
"""Get the initial data from the playlist page."""
172
173
@property
174
def sidebar_info(self) -> dict:
175
"""Get sidebar information from the playlist page."""
176
177
@property
178
def yt_api_key(self) -> str:
179
"""Get the YouTube API key extracted from the page."""
180
```
181
182
### Channel Class
183
184
Handle YouTube channel operations, providing access to all videos uploaded by a specific channel.
185
186
```python { .api }
187
class Channel(Playlist):
188
def __init__(self, url: str, proxies: Optional[Dict[str, str]] = None):
189
"""
190
Initialize a Channel object (inherits from Playlist).
191
192
Args:
193
url (str): YouTube channel URL
194
proxies (dict, optional): HTTP proxy configuration
195
"""
196
```
197
198
### Channel Identification
199
200
Access channel-specific identification properties.
201
202
```python { .api }
203
@property
204
def channel_name(self) -> str:
205
"""Get the channel display name."""
206
207
@property
208
def channel_id(self) -> str:
209
"""Get the unique channel identifier."""
210
211
@property
212
def channel_uri(self) -> str:
213
"""Get the channel URI."""
214
215
@property
216
def vanity_url(self) -> Optional[str]:
217
"""Get the custom channel URL (if available). Returns None if it doesn't exist."""
218
```
219
220
### Channel URLs
221
222
Access different channel page URLs.
223
224
```python { .api }
225
@property
226
def channel_url(self) -> str:
227
"""Get the main channel URL."""
228
229
@property
230
def videos_url(self) -> str:
231
"""Get the channel videos page URL."""
232
233
@property
234
def playlists_url(self) -> str:
235
"""Get the channel playlists page URL."""
236
237
@property
238
def community_url(self) -> str:
239
"""Get the channel community page URL."""
240
241
@property
242
def featured_channels_url(self) -> str:
243
"""Get the featured channels page URL."""
244
245
@property
246
def about_url(self) -> str:
247
"""Get the channel about page URL."""
248
```
249
250
### Channel Page Content
251
252
Access HTML content from different channel pages.
253
254
```python { .api }
255
@property
256
def html(self) -> str:
257
"""Get the main channel page HTML content."""
258
259
@property
260
def playlists_html(self) -> str:
261
"""Get the HTML content of the playlists page."""
262
263
@property
264
def community_html(self) -> str:
265
"""Get the HTML content of the community page."""
266
267
@property
268
def featured_channels_html(self) -> str:
269
"""Get the HTML content of the featured channels page."""
270
271
@property
272
def about_html(self) -> str:
273
"""Get the HTML content of the about page."""
274
```
275
276
### Search Class
277
278
Search YouTube videos with query-based video discovery and result pagination.
279
280
```python { .api }
281
class Search:
282
def __init__(self, query: str):
283
"""
284
Initialize a Search object.
285
286
Args:
287
query (str): Search query string
288
"""
289
```
290
291
### Search Properties
292
293
Access search query information and results.
294
295
```python { .api }
296
@property
297
def query(self) -> str:
298
"""Get the current search query."""
299
300
@property
301
def results(self) -> list:
302
"""
303
Get the list of search result YouTube objects.
304
305
Returns:
306
list: List of YouTube objects from search results
307
"""
308
309
@property
310
def completion_suggestions(self) -> list:
311
"""
312
Get query auto-completion suggestions.
313
314
Returns:
315
list: List of suggested search terms
316
"""
317
```
318
319
### Search Operations
320
321
Manage search results and pagination.
322
323
```python { .api }
324
def get_next_results(self) -> None:
325
"""
326
Load additional search results (pagination).
327
328
Appends new results to the existing results list.
329
"""
330
331
def fetch_and_parse(self, continuation=None) -> Tuple[List[YouTube], str]:
332
"""
333
Fetch and parse a page of search results.
334
335
Args:
336
continuation (str, optional): Continuation token for pagination
337
338
Returns:
339
Tuple[List[YouTube], str]: Tuple of (YouTube objects, next continuation token)
340
"""
341
342
def fetch_query(self, continuation=None) -> dict:
343
"""
344
Fetch raw search query results from YouTube.
345
346
Args:
347
continuation (str, optional): Continuation token for pagination
348
349
Returns:
350
dict: Raw search result data
351
"""
352
```
353
354
## Usage Examples
355
356
### Basic Playlist Download
357
358
```python
359
from pytube import Playlist
360
361
# Initialize playlist
362
playlist = Playlist('https://www.youtube.com/playlist?list=PLrqL3dXNe2Kej3sR4lZ7O2JFXOzd5Y0yV')
363
364
# Get playlist information
365
print(f"Playlist: {playlist.title}")
366
print(f"Owner: {playlist.owner}")
367
print(f"Videos: {playlist.length}")
368
369
# Download all videos
370
for video in playlist.videos:
371
try:
372
print(f"Downloading: {video.title}")
373
stream = video.streams.get_highest_resolution()
374
stream.download()
375
except Exception as e:
376
print(f"Failed to download {video.title}: {e}")
377
```
378
379
### Selective Playlist Processing
380
381
```python
382
from pytube import Playlist
383
384
playlist = Playlist('https://www.youtube.com/playlist?list=PLrqL3dXNe2Kej3sR4lZ7O2JFXOzd5Y0yV')
385
386
# Process only first 5 videos
387
for i, video in enumerate(playlist.videos):
388
if i >= 5:
389
break
390
391
print(f"Video {i+1}: {video.title}")
392
print(f"Duration: {video.length} seconds")
393
print(f"Views: {video.views:,}")
394
print("---")
395
396
# Or use slicing
397
first_five_urls = playlist.video_urls[:5]
398
print(f"First 5 URLs: {first_five_urls}")
399
```
400
401
### Channel Video Discovery
402
403
```python
404
from pytube import Channel
405
406
# Initialize channel
407
channel = Channel('https://www.youtube.com/c/PythonProgramming')
408
409
print(f"Channel: {channel.channel_name}")
410
print(f"Channel ID: {channel.channel_id}")
411
print(f"Total videos: {channel.length}")
412
413
# Get recent videos (first 10)
414
recent_videos = []
415
for i, video in enumerate(channel.videos):
416
if i >= 10:
417
break
418
recent_videos.append({
419
'title': video.title,
420
'views': video.views,
421
'duration': video.length,
422
'publish_date': video.publish_date
423
})
424
425
# Sort by publish date
426
recent_videos.sort(key=lambda x: x['publish_date'], reverse=True)
427
428
for video in recent_videos:
429
print(f"{video['title']} - {video['views']:,} views")
430
```
431
432
### Search and Filter Videos
433
434
```python
435
from pytube import Search
436
437
# Search for videos
438
search = Search('python programming tutorial')
439
440
print(f"Search query: '{search.query}'")
441
print("Completion suggestions:", search.completion_suggestions[:5])
442
443
# Process first page of results
444
print(f"Found {len(search.results)} initial results")
445
446
for video in search.results[:5]:
447
print(f"Title: {video.title}")
448
print(f"Author: {video.author}")
449
print(f"Duration: {video.length // 60}:{video.length % 60:02d}")
450
print(f"Views: {video.views:,}")
451
print("---")
452
453
# Load more results
454
search.get_next_results()
455
print(f"Total results after loading more: {len(search.results)}")
456
```
457
458
### Bulk Download with Progress Tracking
459
460
```python
461
from pytube import Playlist
462
import os
463
from datetime import datetime
464
465
def download_playlist_with_progress(playlist_url, download_dir):
466
"""Download entire playlist with progress tracking."""
467
playlist = Playlist(playlist_url)
468
469
# Create download directory
470
safe_title = "".join(c for c in playlist.title if c.isalnum() or c in (' ', '-', '_')).rstrip()
471
full_download_dir = os.path.join(download_dir, safe_title)
472
os.makedirs(full_download_dir, exist_ok=True)
473
474
print(f"Downloading playlist: {playlist.title}")
475
print(f"Total videos: {playlist.length}")
476
print(f"Download directory: {full_download_dir}")
477
478
successful_downloads = 0
479
failed_downloads = 0
480
481
for i, video in enumerate(playlist.videos, 1):
482
try:
483
print(f"[{i}/{playlist.length}] {video.title}")
484
485
# Get best available stream
486
stream = video.streams.get_highest_resolution()
487
if not stream:
488
stream = video.streams.first()
489
490
# Download with safe filename
491
safe_filename = "".join(c for c in video.title if c.isalnum() or c in (' ', '-', '_')).rstrip()
492
file_path = stream.download(
493
output_path=full_download_dir,
494
filename=safe_filename
495
)
496
497
successful_downloads += 1
498
print(f"✓ Downloaded: {os.path.basename(file_path)}")
499
500
except Exception as e:
501
failed_downloads += 1
502
print(f"✗ Failed: {e}")
503
504
print(f"\nDownload completed!")
505
print(f"Successful: {successful_downloads}")
506
print(f"Failed: {failed_downloads}")
507
508
# Usage
509
download_playlist_with_progress(
510
'https://www.youtube.com/playlist?list=PLrqL3dXNe2Kej3sR4lZ7O2JFXOzd5Y0yV',
511
'./downloads'
512
)
513
```
514
515
### Advanced Collection Filtering
516
517
```python
518
from pytube import Channel
519
from datetime import datetime, timedelta
520
521
def get_recent_channel_videos(channel_url, days=30, min_views=1000):
522
"""Get recent videos from a channel with view threshold."""
523
channel = Channel(channel_url)
524
cutoff_date = datetime.now() - timedelta(days=days)
525
526
recent_videos = []
527
528
for video in channel.videos:
529
# Check if video meets criteria
530
if (video.publish_date and
531
video.publish_date > cutoff_date and
532
video.views >= min_views):
533
534
recent_videos.append({
535
'title': video.title,
536
'url': video.watch_url,
537
'views': video.views,
538
'duration': video.length,
539
'publish_date': video.publish_date
540
})
541
542
# Sort by views (most popular first)
543
recent_videos.sort(key=lambda x: x['views'], reverse=True)
544
545
return recent_videos
546
547
# Usage
548
popular_recent = get_recent_channel_videos(
549
'https://www.youtube.com/c/PythonProgramming',
550
days=60,
551
min_views=5000
552
)
553
554
print(f"Found {len(popular_recent)} popular recent videos:")
555
for video in popular_recent[:10]:
556
print(f"{video['title']} - {video['views']:,} views")
557
```
558
559
### Search with Custom Filters
560
561
```python
562
from pytube import Search
563
564
def search_videos_with_duration_filter(query, min_duration=300, max_duration=1800):
565
"""Search for videos within a specific duration range."""
566
search = Search(query)
567
568
filtered_videos = []
569
processed = 0
570
max_process = 50 # Limit to avoid excessive API calls
571
572
while len(filtered_videos) < 10 and processed < max_process:
573
for video in search.results[processed:]:
574
processed += 1
575
576
# Check duration constraints
577
if min_duration <= video.length <= max_duration:
578
filtered_videos.append({
579
'title': video.title,
580
'author': video.author,
581
'duration': video.length,
582
'views': video.views,
583
'url': video.watch_url
584
})
585
586
if len(filtered_videos) >= 10:
587
break
588
589
# Load more results if needed
590
if len(filtered_videos) < 10 and processed >= len(search.results):
591
search.get_next_results()
592
593
return filtered_videos
594
595
# Usage: Find 5-30 minute Python tutorials
596
medium_tutorials = search_videos_with_duration_filter(
597
'python tutorial beginner',
598
min_duration=300, # 5 minutes
599
max_duration=1800 # 30 minutes
600
)
601
602
for video in medium_tutorials:
603
duration_str = f"{video['duration'] // 60}:{video['duration'] % 60:02d}"
604
print(f"{video['title']} ({duration_str}) - {video['views']:,} views")
605
```
606
607
## Types
608
609
```python { .api }
610
from typing import Dict, List, Optional, Union, Iterable, Iterator, Tuple, Any
611
from datetime import date
612
613
# Deferred generator list for lazy loading
614
class DeferredGeneratorList:
615
"""
616
Lazy-loaded list that generates items on demand.
617
618
A wrapper class for deferring list generation to improve performance
619
when working with large collections like playlists and channels.
620
Items are only fetched and processed when accessed, preventing
621
unnecessary web requests and memory usage.
622
"""
623
624
def __init__(self, generator):
625
"""
626
Initialize DeferredGeneratorList with a generator.
627
628
Args:
629
generator: The deferrable generator to create a wrapper for
630
"""
631
632
def __getitem__(self, key: Union[int, slice]) -> Any:
633
"""
634
Get item(s) by index or slice, generating only as needed.
635
636
Args:
637
key (int or slice): Index or slice object
638
639
Returns:
640
Any: Item(s) at specified index/slice
641
642
Raises:
643
TypeError: If key is not int or slice
644
IndexError: If index is out of range
645
"""
646
647
def __iter__(self) -> Iterator[Any]:
648
"""
649
Iterate through items, generating dynamically.
650
651
Returns:
652
Iterator[Any]: Iterator over generated items
653
"""
654
655
def __len__(self) -> int:
656
"""
657
Get total length by generating all items.
658
659
Returns:
660
int: Total number of items in the collection
661
"""
662
663
def __repr__(self) -> str:
664
"""
665
String representation of all items.
666
667
Returns:
668
str: String representation of the complete list
669
"""
670
671
def __reversed__(self) -> List[Any]:
672
"""
673
Get reversed list of all items.
674
675
Returns:
676
List[Any]: Reversed list of all items
677
"""
678
679
def generate_all(self) -> None:
680
"""
681
Force generation of all items in the collection.
682
683
Useful when you need to access the complete list immediately
684
rather than generating items on-demand.
685
"""
686
687
# Collection filtering types
688
CollectionFilter = Callable[[YouTube], bool]
689
```