Python 网络爬虫 网易云歌单筛选

本文章主要是做一个网络爬虫的实战练习。一是能够对一些爬虫框架有一个初步了解,二是可以练练手,可以做一些简单的网络爬虫项目,达到举一反三的效果,有助于以后深入理解学习更复杂的爬虫项目。

所谓爬虫,就是依据一些规则,对网络上零散的信息进行索引抓取。像百度,google这类的搜索引擎就是具有一定规则的爬虫,当随网络的迅速发展,搜索引擎无法完全满足一些需求,这时就需要对需求定制相应的爬虫规则。

环境(框架)

urllib.request:这是Python自带的库,不需要单独安装,它的作用是为我们打开url获取html的内容。

BeautifulSoup:是python的一个第三方库,它可以从HTML或XML文件中提取数据,并提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。

Selenium:主要是用于网站自动化测试。Selenium 库是一个在WebDriver 上调用的API。WebDriver 有点儿像可以加载网站的浏览器,但是它也可以像BeautifulSoup对象一样用来查找页面元素,与页面上的元素进行交互selenium用于爬虫,主要是用来解决javascript渲染的问题。

Selenium 自己不带浏览器,它需要与第三方浏览器结合在一起使用。例如,Chrome, PhantomJS这类浏览器。这里要注意的是,当selenium打开一个网站时,你桌面是可以看到浏览器被打开的,这样对于数据量大的爬虫无疑是对效率的大打折扣,所以这里需要使用 ‘无头’模式打开。这里不多做赘述,我会在代码中进行具体操作。

实战

在网易云的歌单页面中,有一个分类按钮,它可以对多种类别的内容进行一次筛选,这里就实现一些一个简单的歌单类别筛选,将自己感兴趣的歌单的网页链接爬取下来。

这里要引入一个名词,动态网页。所谓的动态网页,是指跟静态网页相对的一种网页编程技术。静态网页,随着html代码的生成,页面的内容和显示效果就基本上不会发生变化了——除非你修改页面代码。而动态网页则不然,页面代码虽然没有变,但是显示的内容却是可以随着时间、环境或者数据库操作的结果而发生改变的。这也是为什么我们只有同过是用selenium这个类才能正确获取网页内容。

代码

import csv
from selenium import webdriver 
from selenium.webdriver.chrome.options import Options 
import re

#网易云歌单第一页url
url="https://music.163.com/#/discover/playlist"

##设置headless chrome属性
chrome_options=Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.binary_location=r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'

#创建webdriver
driver=webdriver.Chrome(chrome_options=chrome_options)
driver_1=webdriver.Chrome(chrome_options=chrome_options)

#创建存放歌单的csv文件
songlists_file=open("Songlist.csv","w",newline="",encoding="utf-8")
#通过csv对象对文件对象进行操作
writer=csv.writer(songlists_file)
writer.writerow(['歌单','链接'])

#选择需要筛选歌单的类型
type=input("1.流行 2.摇滚 3.民谣 4.说唱\n ")
type=int(type)
#通过选择的类型 生成正则表达式
if type==1:
	pattern=re.compile(r"流行")
elif type==2:
	pattern=re.compile(r"摇滚")
elif type==3:
	pattern=re.compile(r"民谣")
elif type==4:
	pattern=re.compile(r"说唱")
else:
	pattern=None
	
#当前爬取的页数
page=0
	
if not pattern==None:
	while url !="javascript:void(0)":
		#用webdriver打开url
		driver.get(url)
		#切换到内容
		driver.switch_to.frame("contentFrame")
		#定位歌单
		SongSheet=driver.find_element_by_id("m-pl-container").\
					find_elements_by_tag_name("li")
		#获取下一页
		url=driver.find_element_by_css_selector("a.zbtn.znxt").get_attribute("href")
		#对当前页面的歌单进行筛选
		for each in range(len(SongSheet)):
			#获取歌单
			songlist=SongSheet[each].find_element_by_css_selector("a.msk")
			#获取歌单url		
			songlist_url=songlist.get_attribute("href")
			#打开歌单url
			driver_1.get(songlist_url)
			driver_1.switch_to.frame("contentFrame")
			#定位歌单标签
			tag=driver_1.find_element_by_css_selector("div.tags.f-cb").find_elements_by_tag_name("a")
			for each in range(len(tag)):
				#对标签内容进行匹配
				if pattern.match(tag[each].find_element_by_tag_name("i").text):
					writer.writerow([songlist.get_attribute("title"),songlist_url])
			
		page+=1
		print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>num of page: ", page)
#关闭csv文件
songlists_file.close()

结果

注意点

这里也是我在编写代码放的错,通过driver.get()方法加载网页后,内容是实时的,也就是说,当你通过内部方法找到网页元素后,你重新加载其他网页,将导致之前获取的网页元素无法被找到。

猜你喜欢

转载自blog.csdn.net/hengdawei3087/article/details/82422979