Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/nekohacker.py (Python)

Code before:

            # full_response = self._request_webpage(trackurl, id, headers={
            #     'Accept-Encoding': 'identity',
            # })
            # content_type = full_response.headers.get('Content-Type', '').lower()

            upload_date = datetime.strptime(attr['data-releasedate'], '%Y.%m.%d Release')

            entry = {
                'id': id,
                'title': tracktitle,
                'url': trackurl,
                'ext': determine_ext(trackurl),
                'thumbnail': attr['data-albumart'],
                'upload_date': unified_strdate(upload_date.strftime('%Y%m%d'))
            }

            # if re.match(r'audio/', content_type):
            #     entry['vcodec'] = 'none'
            if entry['ext'] == 'mp3':
                entry['vcodec'] = 'none'
                entry['acodec'] = 'mp3'

            entries.append(entry)

        return self.playlist_result(entries, playlist_id, playlist_title)


Review comment (refactor):
This can be simplified and made safer with `traverse_obj`

 - `upload_date = datetime.strptime(attr['data-releasedate'], '%Y.%m.%d Release')` -- this is fatal and should not be, and it throws on other albums (again see https://nekohacker.com/susume/)
 - I think `release_date` is more accurate here than `upload_date`
 - `entry['vcodec'] = 'none'` -- going by the URL attribute name `data-audiopath`, I think this can always be `'none'`, yeah?
 - need to add some imports from utils (and remove some unused imports)

```suggestion
        entries = []
        for track in re.findall(r'(<li[^>]+data-audiopath[^>]+>)', playlist):
            entry = traverse_obj(extract_attributes(track), {
                'url': ('data-audiopath', {url_or_none}),
                'ext': ('data-audiopath', {determine_ext}),
                'id': 'data-trackid',
                'title': 'data-tracktitle',
                'album': 'data-albumtitle',
                'release_date': ('data-releasedate', {lambda x: re.match(r'\d{8}', x.replace('.', ''))}, 0),
                'thumbnail': ('data-albumart', {url_or_none}),
            })
            entry['vcodec'] = 'none'
            entry['acodec'] = 'mp3' if entry['ext'] == 'mp3' else None
            entries.append(entry)

        return self.playlist_result(entries, playlist_id, traverse_obj(entries, (0, 'album')))
```
&nbsp;
Or, it looks like we could also get some more metadata if we want to:
```suggestion
        entries = []
        for track_number, track in enumerate(re.findall(r'(<li[^>]+data-audiopath[^>]+>)', playlist), 1):
            entry = traverse_obj(extract_attributes(track), {
                'url': ('data-audiopath', {url_or_none}),
                'ext': ('data-audiopath', {determine_ext}),
                'id': 'data-trackid',
                'title': 'data-tracktitle',
                'track': 'data-tracktitle',
                'album': 'data-albumtitle',
                'duration': ('data-tracktime', {parse_duration}),
                'release_date': ('data-releasedate', {lambda x: re.match(r'\d{8}', x.replace('.', ''))}, 0),
                'thumbnail': ('data-albumart', {url_or_none}),
            })
            entry['track_number'] = track_number
            entry['artist'] = 'Nekohacker'
            entry['vcodec'] = 'none'
            entry['acodec'] = 'mp3' if entry['ext'] == 'mp3' else None
            entries.append(entry)

        return self.playlist_result(entries, playlist_id, traverse_obj(entries, (0, 'album')))
```

Code after:
        'url': 'https://nekohacker.com/susume/',
        'info_dict': {
            'id': 'susume',
            'title': '進め！むじなカンパニー',
        },
        'playlist': [
            {
                'url': 'https://nekohacker.com/wp-content/uploads/2021/01/進め！むじなカンパニー-feat.-六科なじむ-CV_-日高里菜-割戶真友-CV_-金元寿子-軽井沢ユキ-CV_-上坂すみれ-出稼ぎガルシア-CV_-金子彩花-.mp3',
                'md5': 'fb13f008aa81f26ba48f91fd2d6186ce',
                'info_dict': {
                    'id': '711',
                    'ext': 'mp3',
                    'title': 'md5:1a5fcbc96ca3c3265b1c6f9f79f30fd0',
                    'thumbnail': 'https://nekohacker.com/wp-content/uploads/2021/01/OP表-1024x1024.png',
                    'vcodec': 'none',
                    'acodec': 'mp3',
                    'release_date': '20210115',
                    'album': '進め！むじなカンパニー',
                    'artist': 'Neko Hacker',
                    'track': 'md5:1a5fcbc96ca3c3265b1c6f9f79f30fd0',
                    'track_number': 1,
                    'duration': None
                }
            },
            {
                'url': 'https://nekohacker.com/wp-content/uploads/2021/01/むじな-de-なじむ-feat.-六科なじむ-CV_-日高里菜-.mp3',
                'md5': '028803f70241df512b7764e73396fdd1',
                'info_dict': {
                    'id': '709',
                    'ext': 'mp3',
                    'title': 'むじな de なじむ feat. 六科なじむ (CV: 日高里菜 )',
                    'thumbnail': 'https://nekohacker.com/wp-content/uploads/2021/01/OP表-1024x1024.png',
                    'vcodec': 'none',
                    'acodec': 'mp3',
                    'release_date': '20210115',
                    'album': '進め！むじなカンパニー',
                    'artist': 'Neko Hacker',
                    'track': 'むじな de なじむ feat. 六科なじむ (CV: 日高里菜 )',
                    'track_number': 2,
                    'duration': None
                }
            },
            {
                'url': 'https://nekohacker.com/wp-content/uploads/2021/01/進め！むじなカンパニー-instrumental.mp3',
                'md5': 'adde9e9a16e1da5e602b579c247d0fb9',
                'info_dict': {
                    'id': '710',
                    'ext': 'mp3',
                    'title': '進め！むじなカンパニー (instrumental)',
                    'thumbnail': 'https://nekohacker.com/wp-content/uploads/2021/01/OP表-1024x1024.png',
                    'vcodec': 'none',