摘要:对于这次的爬虫来说,由于网易云音乐以及音乐网页中大部分元素都是使用渲染生成的,因此选择使用来完成这次的脚本。可以发现网易云音乐的手机版歌单地址是。现在已经支持网易云音乐与音乐歌单的互相同步。
本文主要介绍selenium在爬虫脚本的实际应用。适合刚接触python,没使用过selenium的童鞋。(如果你是老司机路过的话,帮忙点个star吧)
项目地址https://github.com/Denon/sync...
selenium介绍selenium官网. 直接引用官网的话
Selenium automates browsers. That"s it! What you do with that power is entirely up to you. Primarily, it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) also be automated as well.
简单翻译下
selenium是一个自动化的浏览器, 主要使用来做web应用的自动化测试。
个人认为用selenium主要的好处是: 可以解析js渲染的页面。对于这次的爬虫来说, 由于网易云音乐以及qq音乐网页中大部分元素都是使用js渲染生成的, 因此选择使用selenium来完成这次的脚本。
环境准备python 2.7
selenium
phantomjs / Chromium
selenium 运行需要额外的浏览器支持. 其中phantomjs可以在这里下载, Chromium可以在这里下载。 前期debug阶段建议使用 Chromium 。
详细的包依赖请查看github项目
初始化selenium
从网易云音乐歌单网页中获取歌曲列表
登录qq音乐
搜索音乐
添加到qq音乐的歌单中
初始化seleniumfrom selenium import webdriver # 这里是使用PhantomJs, 如果使用chromium则使用webdriver.Chrome(), # 并替换对应的驱动路径即可 phantomjs_driver = phantomjs_driver_path opts = Options() opts.add_argument("user-agent={}".format(headers["User-Agent"])) browser = webdriver.PhantomJS(phantomjs_driver)从网易云音乐中获取音乐
对于一般爬虫来说, 如果能用手机端网页爬取那就无脑选网页端爬取。可以发现网易云音乐的手机版歌单地址是: http://music.163.com/m/playli... 。 这个地址么一看就知道, 后面那串id就是歌单id。chrome浏览器打开调试工具, 可以看到所有的歌曲都在...里面。 那么直接用requests + beautifulsoup 爬取元素就好。 这里就不深入讨论了。 具体的代码请参考项目
登录qq音乐一般来说,爬虫做登录有两种选择。一种是抓包,分析登录请求体,直接模拟登录,这种稳定性较好,只要解析出请求体后,登录一般都能成功。一种是模拟正常登录操作,在输入框中输入账号密码,然后点击登录按钮来登录,这种稳定性较差,有可能会有各种意外的情况,比如验证码之类的。这里当然要使用第二种来做(不然就跑题了)。
首先打开qq音乐网站, 发现qq登录的按钮在
这里介绍selenium第一个函数find_element_by_xpath,这个函数就是根据element的xpath来获取元素的。
browser.find_element_by_xpath("/html/body/div[1]/div/div[2]/span/a[2]").click()
点击完后, 页面应该会弹出一个登录框, 不过默认应该是扫码登录, 这个时候就要点击下“帐号密码登录”来切换。可以发现, 这个切换按钮的id是switcher_plogin. 那么使用selenium的 find_element_by_id 函数:
browser.find_element_by_id("switcher_plogin").click()
按理来说这段代码应该能运行成功,但是如无意外的话,我们只能获得一个报错
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"id","selector":"switcher_plogin"}
这是什么情况???
细心点观察可以发现,这个弹出来的登录框是在一个iframe里面。这个时候需要使用到另外一个函数switch_to.frame,
# 切换iframe browser.switch_to.frame("frame_tips") browser.find_element_by_id("switcher_plogin").click() # 输入账号密码, 用到send_keys函数 user_input = browser.find_element_by_id("u") user_input.send_keys("qq_account") pwd_input = self.browser.find_element_by_id("p") pwd_input.send_keys("qq_password") # 最后要切换回来 browser.switch_to.default_content()
可以发现ok了,然后账号密码等输入框直接用上面介绍过的函数直接获取就行。
搜索歌曲在浏览器中打开qq音乐实际搜索一下,发现搜索的url是 https://y.qq.com/portal/search.html#page=1&searchid=1&remoteplace=txt.yqq.top&t=song&w=%E6%B5%AE%E5%A4%B8,可以看到搜索的关键词在 w 这个参数里面,并且中文字是被url encode过的。那么这里使用python内置的urllib2包即可
from urllib2 import quote url_sw = quote(search_word.encode("utf8"))
添加到歌单由于python2坑爹的编码问题, 一般把字符存储成unicode, 在需要使用的时候再转换对应编码比较合适。
人工添加歌单的操作实际分为三步:
鼠标移动到歌曲上
点击 + 号
点击对应的歌单
观察html元素可以发现,搜索出来的歌曲都在
all_song = browser.find_elements_by_class_name("songlist__list")
点击完以后,可以看到歌单的html元素都在里面。
all_playlist = browser.find_elements_by_class_name("operate_menu__item")
而其中每个歌单是以data-dirid这个属性来区分的,这里介绍另外一个元素选择函数find_element_by_css_selector
browser.find_element_by_css_selector("a[data-dirid="{}"]").click()
那么就这样结束了么?
当然不是! 实际运行中发现,这里面大部分元素都是js渲染生成的,直接使用selenium函数去获取这些元素,很大可能会报错
selenium.common.exceptions.ElementNotVisibleException: Message: element not visible
碰到这种情况,最好的解决办法是,用selenium直接执行js脚本来调用元素,selenium执行js脚本的函数为execute_script
browser.execute_script("document.getElementsByClassName("songlist__list")[0].firstElementChild.getElementsByClassName("list_menu__add")[0].click()"
而js代码是可以直接在浏览器上debug的,一般现在浏览器上执行成功在复制回来。
其他一些辅助方法在实际操作中,虽然使用的方法是正确的,但会出现很多意外的情况导致本次操作是失败的,这时候就需要来一次重试来解决问题(如果一次重试解决不了问题,那就来两次)。这里使用一个装饰器来写
def retry(retry_times=0, exc_class=Exception, notice_message=None, print_exc=False): """retry_times: 重试次数 exc_class: 捕捉的异常 notice_message: 提示信息 print_exc: 是否打印错误信息 """ def wrapper(f): @functools.wraps(f) def inner_wrapper(*args, **kwargs): current = 0 while True: try: return f(*args, **kwargs) except exc_class as e: if print_exc: traceback.print_exc() if current >= retry_times: raise RetryException() if notice_message: print notice_message current += 1 return inner_wrapper return wrapper总结
介绍了selenium获取元素的各种用法,更多的请参考文档
解决使用selenium可能会碰到的一些坑。
最后在安利一次github项目, https://github.com/Denon/sync...。欢迎点赞以及提issue。现在已经支持网易云音乐与qq音乐歌单的互相同步。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/38639.html
摘要:基于等开发一款移动端音乐,界面参考了安卓版的网易云音乐布局适配常见移动端。图标使用阿里巴巴图标库,中间的唱片旋转动画使用了实现。搜索功能实现功能搜索歌手歌单歌曲热门搜索数据节流上拉刷新保存搜索记录。 基于 Vue(2.5) + vuex + vue-router + vue-axios +better-scroll + Scss + ES6 等开发一款移动端音乐 WebApp,UI ...
摘要:,在听音乐的时候忽然想听腾格尔的钢铁之翼隐形的翅膀,在网易云上却找不到,就很气。于是想到了做一个,音乐搜索的功能,把所有想听的歌,能够一次性在酷狗网易云虾米等平台上找找完。本项目非常适合新手练习熟悉全家桶,欢迎哦。 React-music React Music WebApp,在听音乐的时候忽然想听腾格尔的钢铁之翼(隐形的翅膀),在网易云上却找不到,就很气。于是想到了做一个,音乐搜索的...
摘要:通常这种加密都是通过加密的,所以首先要找到这个有加密算法的。追踪函数,发现它指向一个叫的函数,仔细研究许久后大概知道加密算法经两次加密获得,模式为,偏移量为。 前言 某宝评论区已经成功爬取了,jd的也是差不多的方法,说实话也没什么好玩的,我是看上它们分析简单,又没加密才拿来试手的。如果真的要看些有趣的评论的话,我会选择网易云音乐,里面汇聚了哲学家,小说家,story-teller,皮皮...
摘要:引言马上情人节就要来了,是否需要一首歌来抚慰你,受伤或躁动的心灵。来吧,今天教你用行代码搞定热门歌单。爬取的效果如下总结本文旨在安抚你因情人节受伤的小心灵,同时带你入个爬虫的门,感受下的强大。 0. 引言 马上314情人节就要来了,是否需要一首歌来抚慰你,受伤或躁动的心灵。来吧,今天教你用15行代码搞定热门歌单。学起来并听起来吧。 本文使用的是Selenium模块,它是一个自动化测试工...
阅读 1718·2021-10-18 13:34
阅读 3904·2021-09-08 10:42
阅读 1551·2021-09-02 09:56
阅读 1604·2019-08-30 15:54
阅读 3126·2019-08-29 18:44
阅读 3297·2019-08-26 18:37
阅读 2212·2019-08-26 12:13
阅读 452·2019-08-26 10:20