本人正在点亮爬虫技能树,写blog以记录
selenium和bs4介绍
Selenium 自动化测试工具。它支持各种浏览器,包括 Chrome,Safari,Firefox 等主流界面式浏览器,如果你在这些浏览器里面安装一个 Selenium 的插件,那么便可以方便地实现Web界面的测试。换句话说叫 Selenium 支持这些浏览器驱动。
Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
观察页面信息
我们爬取页面为网易云音乐的歌手界面,发现不同专栏的url对应的id参数不同,例如:
/#/discover/artist/cat?id=1001 华语男歌手/#/discover/artist/cat?id=1002 华语女歌手…
在发现对应的每个专栏的A-Z索引对应的initial参数不同,例如:/#/discover/artist/cat?id=1001&initial=65 华语男歌手A索引/#/discover/artist/cat?id=100ini1&initial=66 华语男歌手B索引…
从A-Z对应initial参数65-90
通过更改url后面的id参数和initial参数获得不同页面
def main():url = '/#/discover/artist/cat?id='items = [1001,1002,1003,2001,2002,,4001,4002,4003,6001,6002,6003,7001,7002,7003]initials = [-1] + [i for i in range(65,91)] #-1为热门索引for item in items:for initial in initials:new_url = url + str(item) + '&initial=' + str(initial)src = get_page(new_url)# print(src)singer_info = parse_html(src)
好!
主函数搞定,然后写get_page和parse_html方法
获取源代码
首先尝试过用webdriver直接获取网页源代码
driver = webdriver.Chrome('E:/code/scrapy/chromedriver.exe')#chromedriver路径driver.get(url)page_src = driver.page_source
发现拿到的page_src一点歌手信息都没有QAQ
然后发现歌手信息都在frame框架源代码中,用switch_to_frame转入框架再获取一遍
def get_page(url):chromeOptions = webdriver.ChromeOptions()chromeOptions.add_argument('headless')#设置headless参数,浏览器不弹出driver = webdriver.Chrome('E:/code/scrapy/chromedriver.exe',options = chromeOptions)driver.get(url)driver.switch_to.frame('g_iframe')page_src = driver.page_sourcedriver.close()return page_src
我拿到了这个网页的框架源代码,剩下的工作把歌手名字和歌手id从html中解析出来就可以了!
解析
<a href="/artist?id=1875" class="nm nm-icn f-thide s-fc0" title="阿信的音乐">阿信</a></li><li class="sml"><a href="/artist?id=12441083" class="nm nm-icn f-thide s-fc0" title="傲日其愣的音乐">傲日其愣</a></li><li class="sml"><a href="/artist?id=14469086" class="nm nm-icn f-thide s-fc0" title="阿金和玄子的音乐">阿金和玄子</a></li><li class="sml"><a href="/artist?id=13222299" class="nm nm-icn f-thide s-fc0" title="安浩辰的音乐">安浩辰</a></li>
观察发现歌手信息都在一个class = “nm nm-icn f-thide s-fc0"的标签中
获取其文本内容可以的到singer_name
将 href 中的’/artist?id=’ 替换成”" 就可以获得singer_id
def parse_html(html):soup = BeautifulSoup(html,'lxml')for singer in soup.find_all('a',attrs={'class':'nm nm-icn f-thide s-fc0'}):singer_name = singer.stringsinger_id = singer['href'].replace('/artist?id=','').strip()# singer_info = [singer_id,singer_name]sql.insert_singer(singer_id, singer_name)#储存进数据库
写入mysql
存入数据库的方法(pymsql连接mysql):
用try,except 接收error,以免出现重复id的时候报错停止循环
import pymysqldb = pymysql.connect(host = 'localhost',#本地user = 'root',password = '123456',db = 'music163',cursorclass=pymysql.cursors.DictCursor)def insert_singer(singer_id, singer_name):with db.cursor() as cursor:sql = "INSERT INTO `artist`(`singer_id`,`singer_name`) VALUES (%s, %s)"try:cursor.execute(sql,(singer_id, singer_name))mit()except:db.rollback()
然后运行主函数就可以拉!
最后爬到了34167条歌手记录,因为访问次数较少,没有设置代理,若访问次数较多,建议设置代理池,必然容易被封ip。
Reference:
/1052.html
/NacedWang/163MusicSpider
/zyingzhou/music163-spiders