Python で qq music をクロールする処理の例

零下一度
リリース: 2017-07-18 15:28:28
オリジナル
4063 人が閲覧しました

1. はじめに


QQ ミュージックにはまだたくさんの音楽がありますが、時々、良い音楽をダウンロードしたいのですが、Web ページでダウンロードするたびにログインする必要があります。 。そこで、qqmusic クローラーの登場です。少なくとも、for ループ クローラーにとって最も重要なことは、クロールされる要素の URL を見つけることだと思います。以下を見てみましょう (間違っていても笑わないでください)

<br>

2. Python が QQ 音楽シングルをクロールします


MOOC.com で見たビデオで非常にわかりやすく説明されています。また、一般的なクローラーの作成手順に従います。

1.ターゲットを決める

まず、今回はQQ Musicの歌手Andy Lauのシングルをクロールしました。 (Baidu Encyclopedia) -> 分析対象 (戦略: URL 形式 (範囲)、データ形式、Web ページのエンコーディング) -> コードを作成 -> クローラーを実行

2. 分析対象

link : 左のスクリーンショットを見ると、シングル曲の情報がページングされていて、各ページに 30 項目、合計 30 ページ表示されていることがわかります。ページ番号または右端の「>」をクリックすると、ブラウザがサーバーに非同期 Ajax リクエストを送信し、これを表す begin パラメータと num パラメータが表示されます。それぞれ開始曲の添え字 (スクリーンショットは 2 ページ目、開始添え字は 30) で、1 ページは 30 項目を返し、サーバーは曲情報を json 形式で返して応答します (MusicJsonCallbacksinger_track({"code":0,"data": {"list":[{"Flisten_count1":. .....]}))、曲情報だけを取得したい場合は、リンク リクエストを直接結合し、返された json 形式のデータを解析できます。ここでは、データ形式を直接解析する方法を使用せず、各ページの単一情報を取得して解析した後、「>」をクリックして次のページに移動し、すべての情報が取得されるまで解析を続けます。単一の情報が解析されて記録されます。最後に、各シングルのリンクをリクエストして、詳細なシングル情報を取得します。

右側のスクリーンショットは、Web ページのソース コードです。すべての曲情報は、クラス名が mod_songlist の div フローティング レイヤー内にあり、クラス名が Songlist_list の順序なしリスト ul の下にあります。 li 要素はシングルを表示します。クラス名 Songlist__album の下の a タグには、シングルのリンク、名前、期間が含まれます。

3. コードを書く

1) ここでは、Python の Urllib 標準ライブラリを使用し、ダウンロード メソッドをカプセル化します。 ) を解析しますWeb ページのコンテンツ、ここではサードパーティのプラグイン BeautifulSoup が使用されます。詳細については、BeautifulSoup API を参照してください。

def download(url, user_agent='wswp', num_retries=2):
    if url is None:
        return None
    print('Downloading:', url)
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
    request = urllib.request.Request(url, headers=headers)  # 设置用户代理wswp(Web Scraping with Python)
    try:
        html = urllib.request.urlopen(request).read().decode('utf-8')
    except urllib.error.URLError as e:
        print('Downloading Error:', e.reason)
        html = None
        if num_retries > 0:
            if hasattr(e, 'code') and 500 <= e.code < 600:
                # retry when return code is 5xx HTTP erros
                return download(url, num_retries-1)  # 请求失败,默认重试2次,
    return html
ログイン後にコピー
def music_scrapter(html, page_num=0):
    try:
        soup = BeautifulSoup(html, 'html.parser')
        mod_songlist_div = soup.find_all('div', class_='mod_songlist')
        songlist_ul = mod_songlist_div[1].find('ul', class_='songlist__list')
        '''开始解析li歌曲信息'''
        lis = songlist_ul.find_all('li')
        for li in lis:
            a = li.find('div', class_='songlist__album').find('a')
            music_url = a['href']  # 单曲链接
            urls.add_new_url(music_url)  # 保存单曲链接
            # print('music_url:{0} '.format(music_url))
        print('total music link num:%s' % len(urls.new_urls))
        next_page(page_num+1)
    except TimeoutException as err:
        print('解析网页出错:', err.args)
        return next_page(page_num + 1)
    return None
ログイン後にコピー
4. クローラーを実行します

def get_music():
     try:
        while urls.has_new_url():
            # print('urls count:%s' % len(urls.new_urls))
            '''跳转到歌曲链接,获取歌曲详情'''
            new_music_url = urls.get_new_url()
            print('url leave count:%s' % str( len(urls.new_urls) - 1))
            html_data_info = download(new_music_url)
            # 下载网页失败,直接进入下一循环,避免程序中断
            if html_data_info is None:
                continue
            soup_data_info = BeautifulSoup(html_data_info, 'html.parser')
            if soup_data_info.find('div', class_='none_txt') is not None:
                print(new_music_url, '   对不起,由于版权原因,暂无法查看该专辑!')
                continue
            mod_songlist_div = soup_data_info.find('div', class_='mod_songlist')
            songlist_ul = mod_songlist_div.find('ul', class_='songlist__list')
            lis = songlist_ul.find_all('li')
            del lis[0]  # 删除第一个li
            # print('len(lis):$s' % len(lis))
            for li in lis:
                a_songname_txt = li.find('div', class_='songlist__songname').find('span', class_='songlist__songname_txt').find('a')
                if 'https' not in a_songname_txt['href']:  #如果单曲链接不包含协议头,加上
                    song_url = 'https:' + a_songname_txt['href']
                song_name = a_songname_txt['title']
                singer_name = li.find('div', class_='songlist__artist').find('a').get_text()
                song_time =li.find('div', class_='songlist__time').get_text()
                music_info = {}
                music_info['song_name'] = song_name
                music_info['song_url'] = song_url
                music_info['singer_name'] = singer_name
                music_info['song_time'] = song_time
                collect_data(music_info)
     except Exception as err:  # 如果解析异常,跳过
         print('Downloading or parse music information error continue:', err.args)
ログイン後にコピー
<span style="font-size: 16px;">爬虫跑起来了,一页一页地去爬取专辑的链接,并保存到集合中,最后通过get_music()方法获取单曲的名称,链接,歌手名称和时长并保存到Excel文件中。</span><br><span style="font-size: 14px;"><img src="https://img.php.cn/upload/article/000/000/001/a1138f33f00f8d95b52fbfe06e562d24-4.png" alt=""    style="max-width:90%"  style="max-width:90%"><strong><img src="https://img.php.cn/upload/article/000/000/001/9282b5f7a1dc4a90cee186c16d036272-5.png" alt=""></strong></span>
ログイン後にコピー
3. シングルはページングを使用し、次のページに切り替えるには、非同期 ajax リクエスト Ob を使用します。汚れるサーバーから json 形式のデータを取得してページにレンダリングします。ブラウザーのアドレス バーのリンクは変更されず、結合されたリンクを通じてリクエストすることはできません。最初は Python Urllib ライブラリを使用して ajax リクエストをシミュレートすることを考えましたが、その後 Selenium を使用することを考えました。 Selenium はブラウザの実際の動作を非常によくシミュレートでき、ページ要素の配置も非常に便利です。次のページをクリックし、常に単一のページネーションを切り替え、その後 BeautifulSoup を通じて Web ページのソース コードを解析して単一のページを取得することをシミュレートします。情報。

<br>

2.url リンク マネージャーは、コレクション データ構造を使用して単一のリンクを保存します。なぜコレクションを使用するのですか?同じアルバムから複数のシングルが (同じアルバム URL で) 取得される可能性があるため、これによりリクエストの数を減らすことができます。

<br>
ログイン後にコピー
class UrlManager(object):<br>    def __init__(self):<br>        self.new_urls = set()  # 使用集合数据结构,过滤重复元素<br>        self.old_urls = set()  # 使用集合数据结构,过滤重复元素
ログイン後にコピー
3. Python サードパーティのプラグイン openpyxl

を使用して Excel を読み書きするのは非常に便利で、単一の情報は Excel ファイルを通じて適切に保存できます。

    def add_new_url(self, url):<br>        if url is None:<br>            return<br>        if url not in self.new_urls and url not in self.old_urls:<br>            self.new_urls.add(url)<br><br>    def add_new_urls(self, urls):<br>        if urls is None or len(urls) == 0:<br>            return<br>        for url in urls:<br>            self.add_new_url(url)<br><br>    def has_new_url(self):<br>        return len(self.new_urls) != 0<br><br>    def get_new_url(self):<br>        new_url = self.new_urls.pop()<br>        self.old_urls.add(new_url)<br>        return new_url<br><br>
ログイン後にコピー

4. 追記

最後に、QQ Music のシングル情報をクロールすることに成功したことをお祝いしなければなりません。今回は、Selenium が不可欠な単一のクロールに成功しました。今回は、Selenium のいくつかの簡単な機能のみを使用しました。今後は、クローラーだけでなく UI 自動化の面でも Selenium について詳しく学習します。

今後最適化が必要な点:

1. ダウンロードリンクが多く、一つ一つダウンロードするのが遅い 今後はマルチスレッドの同時ダウンロードを使用する予定です。

2. ダウンロード速度が速すぎるため、サーバーが IP を無効にし、同じドメイン名へのアクセスが頻繁に発生する問題を回避するために、各リクエストの間に待機メカニズムと待機間隔が設けられています。

3. Web ページの解析は重要なプロセスです。現在、BeautifulSoup ライブラリは lxml ほど効率的ではありません。 lxmlは後で。

以上がPython で qq music をクロールする処理の例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!