当前位置: 首页 > Web前端 > HTML5

Python爬虫学习教程,爬取网易云音乐!

时间:2023-04-05 22:28:25 HTML5

运行环境我的运行环境如下:系统版本Windows10。Python版本为Python3.5。推荐使用科学计算版Anaconda,主要是自带包管理工具,可以解决部分包安装出错的问题。进入Anaconda官网,选择Python3.5版本,然后下载安装。我使用的IDE是PyCharm,这是一款专门为Python开发的IDE。这是JetBrians的实际产品。上文提到,网易云音乐的网页与普通网页相比主要有两个不同:网页是js动态加载的,使用iframe框架。所以,首先网页请求不能使用requests库。使用硒+PhatomJS。其次,使用Selenium+PhatomJS后,需要对iframe做特殊处理。废话不多说,来看看实际操作步骤:首先打开网页http://music.163.com,在右上角的搜索框中输入“TheBeatles”,然后会出现一个下拉——下拉选项,选择歌手TheBeatles(红框内的内容)。然后看到如下页面,选择红框中的“所有相册”,点击。这会将您带到所有相册的列表,下面有翻页按钮。我们只需要所有专辑的图片、专辑名称和专辑发行日期。看到这里,就可以想象爬虫的爬取逻辑了。定位到页面,然后获取页码,然后一个一个请求页面,爬取页面中的内容。点击翻页按钮,查看url中是否有规则。点击第二页后,看到上面的地址栏!!!看到这个地址栏,懒得翻页了。..limit参数是限制一个页面加载相册的数量。offset参数是之前过滤了多少张专辑。现在一页有12个相册,所以第二页offset=12,第三页offset=24,以此类推。..一共9页,每页12页,不到120页。所以……换个url就不用翻页了!!limit参数等于120,offset参数等于0,大功告成!输入下面的url以查看是否所有相册都已加载。http://music.163.com/#/artist/album?id=101988&limit=120&offset=0下面开始爬虫代码。这里我们会用到上一篇博文写的几个工具和方法:'''学习过程中有什么不懂的可以加我的python学习交流按钮qun。934109170群ToolsandeBooks里面有很好的学习教程和开发。跟大家分享一下目前python公司的人才需求以及如何从零开始学好python,学什么。'''defsave_img(self,url,file_name):##保存图片print('开始请求图片地址,过程会有点长...')img=self.request(url)print('开始保存图片')f=open(file_name,'ab')f.write(img.content)print(file_name,'图片保存成功!')f.close()defrequest(self,url):#encapsulatedrequestsrequestr=requests.get(url)#发送一个像目标url地址一样的get请求,返回一个response对象。有或没有headers参数。returnrdefmkdir(self,path):##Thisfunctioncreatesafolderpath=path.strip()isExists=os.path.exists(path)ifnotisExists:print('创建一个名为',path,'的文件夹文件夹')os.makedirs(path)print('创建成功!')returnTrueelse:print(path,'文件夹已经存在,不会再创建')returnFalsedefget_files(self,path):#Get文件夹中的文件名列表pic_names=os.listdir(path)returnpic_namesOK,开始我们的爬虫逻辑部分:这里值得注意的是这个页面使用了frame框架,使用Selenium+PhantomJS后不会加载iframe框架网页内容。iframeframe相当于在页面中加载另一个页面,需要使用Selenium的switch_to.frame()方法加载(官网给出的方法是switch_to_frame(),IDE提示改用之前的方法).看下面的网页结构,iframe的id是“g_iframe”:加载iframe框架中的内容:driver=webdriver.PhantomJS()driver.get(self.init_url)driver.switch_to.frame("g_iframe")html=驱动程序。page_source然后找到所有的封面元素:根据上面的网页结构,所有的专辑信息都在ul标签中,每个专辑在一个li标签中。li标签包含图片url、相册名称和相册时间。只需抓住它的内容。all_li=BeautifulSoup(html,'lxml').find(id='m-song-module').find_all('li')forliinall_li:album_img=li.find('img')['src']album_name=li.find('p',class_='dec')['title']album_date=li.find('span',class_='s-fc3').get_text()这里获取的图片url还是图片有宽高参数,所以过滤宽高参数:http://p4.music.126.net/pLA1G...过滤掉问号后面的参数:end_pos=album_img.index('?')#找到问号的位置album_img_url=album_img[:end_pos]#截取问号前的内容命名逻辑:专辑时间+专辑名。专辑名称可能有一些特殊字符需要替换!photo_name=album_date+'-'+album_name.replace('/','').replace(':',',')+'.jpg'然后使用上一篇博文示例中的去重逻辑,修改后爬虫逻辑部分如下:defspider(self):print("Start!")driver=webdriver.PhantomJS()driver.get(self.init_url)driver.switch_to.frame("g_iframe")html=driver.page_sourceself.mkdir(self.folder_path)#创建文件夹print('开始切换文件夹')os.chdir(self.folder_path)#切换路径到上面创建的文件夹file_names=self.get_files(self.folder_path)#获取文件文件夹内所有文件名,类型为listall_li=BeautifulSoup(html,'lxml').find(id='m-song-module').find_all('li')#print(type(all_li))forliinall_li:album_img=li.find('img')['src']album_name=li.find('p',class_='dec')['title']album_date=li.find('span',class_='s-fc3').get_text()end_pos=album_img.index('?')album_img_url=album_img[:end_pos]photo_name=album_date+'-'+album_name.replace('/','').replace(':',',')+'.jpg'print(album_img_url,photo_name)ifphoto_nameinfile_names:print('图片已经存在,noDownloadagain')else:self.save_img(album_img_url,photo_name)其实相比上一篇博文的例子,这个爬虫的逻辑部分还是比较简洁的。fromseleniumimportwebdriverfrombs4importBeautifulSoupimportrequestsimportosclassAlbumCover():def__init__(self):self.init_url="http://music.163.com/#/artist/album?id=101988&limit=120&offset=0"#RequestURLself.folder_path="C:\D\TheBeatles"#想要存放文件的目录defsave_img(self,url,file_name):##保存图片print('开始请求图片地址,过程会有点long...')img=self.request(url)print('开始保存图片')f=open(file_name,'ab')f.write(img.content)print(file_name,'图片已保存successful!')f.close()defrequest(self,url):#封装请求requestr=requests.get(url)#发送get请求,如目标url地址,返回响应对象。有或没有headers参数。returnrdefmkdir(self,path):##Thisfunctioncreatesafolderpath=path.strip()isExists=os.path.exists(path)ifnotisExists:print('创建一个名为',path,'的文件夹Folder')os.makedirs(path)print('创建成功!')returnTrueelse:print(path,'文件夹已经存在,不会再创建')returnFalsedefget_files(self,path):#get文件夹中的文件名列表pic_names=os.listdir(path)returnpic_namesdefspider(self):print("Start!")driver=webdriver.PhantomJS()driver.get(self.init_url)driver.switch_to.frame("g_iframe")html=driver.page_sourceself.mkdir(self.folder_path)#创建文件夹print('开始切换文件夹')os.chdir(self.folder_path)#切换路径到上面创建的文件夹file_names=self.get_files(self.folder_path)#获取文件夹中的所有文件名,类型为listall_li=BeautifulSoup(html,'lxml').find(id='m-song-module').find_all('li')#打印(类型(all_li))对于all_li中的li:album_img=li.find('img')['src']album_name=li.find('p',class_='dec')['title']album_date=li.find('span',class_='s-fc3').get_text()end_pos=album_img.index('?')album_img_url=album_img[:end_pos]photo_name=album_date+'-'+album_name.replace('/','').replace(':',',')+'.jpg'print(album_img_url,photo_name)ifphoto_nameinfile_names:print('图片已经存在,不会再下载')else:self.save_img(album_img_url,photo_name)album_cover=AlbumCover()album_cover.spider()执行结果:查看文件夹里面有什么: