第二十九篇 ajax动态网页爬取,豆瓣电影,网易云音乐,千千音乐

心得:每天进步一点点,不懂得去查询,去学习,自己慢慢会进步的更多。

自己在学习过程中总结出来的爬虫的过程:
1.导入库,确定要用到的库
2.确定要爬取的url:
动态网页往往隐藏了在XHR,JS页面内,需要发掘和寻找,找出的数据往往是json格式的数据,需要进一步去提取。(ajax加载)
今天的重点在这里,如何破解ajax网页,抓取想要的内容。
3.数据解析:
三种解析方式,正则表达式,BeautifulSoup,xpath 提取需要的数据
4.持久化存储:

动态加载实例

1.豆瓣电影名称和评分的抓取

看看豆瓣排行榜的网页:
在这里插入图片描述
可以看到预览(preview)这一栏的东西只是一个空壳子,而且此网页的请求的地址和我们网站输入的地址一样,所以更加确定这是一个ajax请求的网站了。
在这里插入图片描述
找不到我们需要的电影名称和评分,我们就需要去ALL里面找其他的返回网页,看看有没有我们需要的关键字。
在这里插入图片描述
在一个top_list的一栏中找到了我们需要的信息,但它是以json格式存储的,所以我们此页面对相应的url发出请求,才可以获得完整的数据,再进行解析,筛选。
在这里插入图片描述
在这里插入图片描述
此网页是一个get并且带参数的,所以我们也需要再代码中加入参数进行抓取,带参数的url问号之后的参数可以删掉,将参数的值加入params中传入请求。

介绍一种读取json格式的方法,有时对json格式内容不好抓取,可以将json转换为更清晰的格式:
将json转换为更清晰的格式

看代码:

#coding=utf-8
import requests
import json

dou_url="https://movie.douban.com/j/chart/top_list"
params={
    "type": "25", #5动作 #11剧情 24喜剧 20恐怖 10悬疑 19惊悚
    "interval_id": "100:90",
    "action": "",
    "start": "0", #从第几部电影去取
    "limit": "1000" #一次取多少部电影
}
headers={
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"
}
response=requests.get(url=dou_url,params=params,headers=headers)
for i in response.json():
    if float(i['score']) >= 9:
        print(i['title']+" : "+str(i['score']))

结果:

PS C:\Users\TianJian\Desktop\python> & C:/Users/TianJian/AppData/Local/Microsoft/WindowsApps/python.exe c:/Users/TianJian/Desktop/python/requests_1028/豆瓣电影高分.py
大雄的怀念奶奶 : 9.5
拽妹黛薇儿要上大学了没 : 9.4
千与千寻 : 9.3
机器人总动员 : 9.3
大闹天宫 : 9.3
虚幻勇士 : 9.3
苏联动画大师作品精选集 : 9.3

2.网易云音乐爬取,附加音乐的歌词。
网易云的动态加载做到了极致,它的音乐播放地址是一个外部链接,歌词链接也是一个外部链接,先看看它对应的url是什么:
因为它是动态加载我直接找到了,它对应的动态加载的url。
在这里插入图片描述
可以看到歌词的参数是被加密过的,我们不可能对加密的参数再进行请求,所以直接找到了它的外部

链接地址:

url="http://music.163.com/song/media/outer/url?id=1400256289.mp3"    #外链播放地址
lrc_url="http://music.163.com/api/song/lyric?id=3932159&lv=1&kv=1&tv=-1"   #外链歌词地址

我们拿到了外部链接地址,只需要再拿到对应的id就可以抓到对应的歌和歌词。

#coding=utf-8

import os
import re
import json
import requests
from lxml import etree
from bs4 import BeautifulSoup

filepath="C:\\Users\\TianJian\\Desktop\\python\\数据解析1107\\top_music\\"  #定义存储路径

if not os.path.exists(filepath):   #创建路径
    os.mkdir(filepath)

headers={          #定义headers
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"
    }

def down_song(song_url,song_path,name,headers):   #获得song_url后,下载歌曲
    song_r=requests.get(url=song_url,headers=headers).content
    with open(song_path,"wb") as f:
        f.write(song_r)
        print(name+" : 下载完成 ")


def down_lyric(lrc_url,lyric_path,name,headers):  #获得lyric_url后,下载歌词
    r=requests.get(url=lrc_url,headers=headers).text
    try:                                              #有些歌曲歌词不存在,需要用try过度
        lyric=json.loads(r)['lrc']['lyric']           #歌词url是一个json格式的文件,我们需要加载才可以使用
        lyric_r=re.sub(r'\[.*\]','',lyric)            #正则取剔除无用的信息
        with open(lyric_path,"w",encoding="utf-8") as f:
            f.write(lyric_r)
            print(name+" : 歌词 下载完成 ")
    except:
        print(name+"的歌词不存在~~~")
        pass

    
#url="http://music.163.com/song/media/outer/url?id=1400256289.mp3"    #外链播放地址
#lrc_url="http://music.163.com/api/song/lyric?id=3932159&lv=1&kv=1&tv=-1"   #外链歌词地址

#url="https://music.163.com/discover/toplist?id=3779629"   #top榜
#url="https://music.163.com/discover/toplist?id=1978921795"  #电音榜
url="https://music.163.com/discover/toplist?id=2250011882"  #抖音榜
song_base_url="http://music.163.com/song/media/outer/url?id="  
lrc_base_url = 'http://music.163.com/api/song/lyric?id='

s = requests.session()
r=s.get(url=url,headers=headers).content        #需要content来提取信息

etree=etree.HTML(r)
title=etree.xpath('//a[contains(@href,"song?")]/text()')[:-3]   #抓取歌名,后三位无用信息,切片拿掉
id=etree.xpath('//ul[@class="f-hide"]/li/a/@href')  #抓取歌id

for name,i in zip(title,id):        #遍历
    song_id=i.split('=')[-1]       #分割,取得id
    song_url=song_base_url+song_id+".mp3"   #歌url加工
    song_path=filepath+name+".mp3"   #歌存储路径加工

    lrc_url=lrc_base_url+song_id+'&lv=1&kv=1&tv=-1'  #词url加工
    lyric_path=filepath+name+".txt"  #词存储路径加工

    down_song(song_url,song_path,name,headers)   #分别调用
    down_lyric(lrc_url,lyric_path,name,headers)

3.千千音乐爬取:
看看动态的mp3信息:
在这里插入图片描述
url内含有一串加密过的字符串,我们不能对加密的字符串进行提取,继续找,在js页面中找到了关于音乐id关联的东西:

在这里插入图片描述
然后我们对此网页进行解析发现,替换id之后可以将对应的音乐直接访问,所以我们需要抓取id就行,我们用静态网页抓取的方法抓取了hot_top页面歌曲的id,逐一进行下载存储。
在这里插入图片描述

#coding=utf-8
import requests
from lxml import etree
import json
import os

filepath="C:\\Users\\TianJian\\Desktop\\python\\数据解析1107\\music\\"
# for tu_file in os.listdir(filepath):    #删除文件夹内的文件
#     os.remove(filepath+str(tu_file))
if not os.path.exists(filepath):
    os.mkdir(filepath)

url="http://music.taihe.com/top/dayhot"
base_url="http://musicapi.taihe.com/v1/restserver/ting?method=baidu.ting.song.playAAC&songid="
headers={
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"
    }
r=requests.get(url=url,headers=headers).content.decode()

f_etree=etree.HTML(r)
music_name=f_etree.xpath('//div[@class="song-item"]/span[@class="song-title "]/a[contains(@href,"/song/")]/text()')
music_id=f_etree.xpath('//li/div[@class="song-item"]/span[@class="song-title "]/a[contains(@href,"/song/")]/@href')
#print(len(music_id))

for id,name in zip(music_id,music_name):
    second_url=base_url+id.split('/')[-1]
    #print(second_url,name)
    sec_r=requests.get(url=second_url,headers=headers).text
    sec_etree=etree.HTML(sec_r)
    three_url=sec_etree.xpath('//body//text()')[0]
    three_u=json.loads(three_url)
    three_ur=three_u['bitrate']['show_link']
    three_r=requests.get(url=three_ur,headers=headers).content
    if '/' in name:
        name=name.replace('/','')
    downloadpath=filepath+name+".mp3"
    with open(downloadpath,'wb') as f:
        f.write(three_r)
        print(name+" 下载完成")

mp3存储时,写入的格式为wb格式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值