感谢提供素材的同学,无论好坏,高低,我都真心佩服你:参考文章地址:https://mp.weixin.qq.com/s/AXr8BjR_tU-E9YBo-mLVlg
在上一篇的文章中,总结了爬虫的四个步骤,之后的爬虫也大都会按照这四个步骤去分析。因为这样分析更有利于我们去看清问题所在,看看我们爬虫所面对的难点是在那个步骤上,然后我们也可以做到心里有数,让我们去学习更加有目标。
在这里定下一个小目标:爬取网易云播放数大于500万的歌单
我们第一步可能会去尝试着去使用前面的urllib去获取网页源代码,在这里我们先尝试一下:获取的东西是什么?
代码:
html = urlopen('http://music.163.com/#/discover/playlist/?order=hot&cat=%E5%85%A8%E9%83%A8&limit=35&offset=0') print(html)
结果:
很明显,我们按照这种方法是没有办法拿到源代码的,
现在的问题就是:我们获取不到源代码。我们也发现问题是:网站的HTML页面没有运行javaScript,那我们的问题是让我们爬取的html页面运行javaScript即可。
文章中的解决方法是 Selenium + PhantomJS (因为时代的变迁,PhantomJS已经不被selenium所支持)
我的解决方法是:Selenium + ChromeDriver
selenium是一款十分神奇的工具--------作者(我)这样觉得
使用selenium需要自己去下载,如果是基于pycharm开发,那么可以使用File-->settings
来添加selenium.
ChromeDriver是要自己去下载的,下载的地址是:https://chromedriver.storage.googleapis.com/index.html
下载之前你得先看看chrome的版本,然后根据版本来下载对应的版本。版本查看地址:https://blog.csdn.net/huilan_same/article/details/51896672
下载好之后放到chrome.exe同级目录下即可。
csv的文件如果使用pycharm打开会乱码,因为是他的编码是gbk,你的是utf-8
因为代码中有注释,所以就直接上代码了
总结的代码如下:
# -*- coding:utf-8 -*- from selenium import webdriver from selenium.webdriver.chrome.options import Options import csv url = 'http://music.163.com/#/discover/playlist/?order=hot&cat=%E5%85%A8%E9%83%A8&limit=35&offset=0' # 用PhantomJS接口创建一个selemium的webDriver # driver = webdriver.PhantomJS(executable_path="D:\phantomjs\phantomjs-2.1.1-windows\bin\phantomjs.exe") chrome_options = Options() chrome_options.add_argument('--headless') #使用headless模式 chrome_options.add_argument('--disable-gpu') #不使用GPU加速 driver = webdriver.Chrome(executable_path='C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe', chrome_options=chrome_options) # 准备好存储歌单的csv文件 csv_file = open("playlist.csv", "w", newline='', encoding='gb18030') writer = csv.writer(csv_file) writer.writerow(['标题', '播放数', '链接']) # browser = webdriver.Chrome('C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe') # browser.get('http://www.baidu.com/') # 解析每一页直到下一页为空 while url != 'javascript:void(0)': driver.get(url) driver.switch_to.frame("contentFrame") data = driver.find_element_by_id("m-pl-container").find_elements_by_tag_name("li") for i in range(len(data)): nb = data[i].find_element_by_class_name("nb").text if '万' in nb and int(nb.split("万")[0]) > 500: msk = data[i].find_element_by_css_selector("a.msk") writer.writerow([msk.get_attribute("title"), nb, msk.get_attribute("href")]) url = driver.find_element_by_css_selector("a.zbtn.znxt").get_attribute('href') csv_file.close()
在写完爬取网易云的歌单后,有些心痒痒的,于是决定爬取一下QQ音乐的榜单。
心里os:好像只有一个网址变化了,其他的好像没有多少变化,于是心里莫名激动,两三下就改完了。一运行结果就报错了。
总结一下:1.数量的标签中含有中文,解决方法:使用字符串替换,替换掉多余的中文字符
2. 翻页的时候没有具体的url,解决方法:使用标签内的属性来拼接url,在访问即可。
总的步骤和思想跟爬取网易音乐差不多。
代码如下:
# -*- coding:utf-8 -*- from selenium import webdriver from selenium.webdriver.chrome.options import Options import csv import time url = 'https://y.qq.com/portal/playlist.html#t3=' # 用PhantomJS接口创建一个selemium的webDriver # driver = webdriver.PhantomJS(executable_path="D:\phantomjs\phantomjs-2.1.1-windows\bin\phantomjs.exe") chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') driver = webdriver.Chrome(executable_path='C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe', chrome_options=chrome_options) # 准备好存储歌单的csv文件 csv_file = open("QQplaylist.csv", "w", newline='', encoding='gb18030') writer = csv.writer(csv_file) writer.writerow(['标题', '播放数', '链接']) # browser = webdriver.Chrome('C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe') # browser.get('http://www.baidu.com/') # 解析每一页直到下一页为空 count = 1 max_num = 0 while url != 'javascript:void(0)': try: url = 'https://y.qq.com/portal/playlist.html#t3=' url = url + str(count) + '&' print(url) driver.get(url) # driver.switch_to.frame("contentFrame") time.sleep(1) data = driver.find_element_by_id("playlist_box").find_elements_by_tag_name("li") if max_num == 0 : index_data = driver.find_elements_by_class_name("js_pageindex") max_num = int(index_data[3].get_attribute("data-index")) for i in range(len(data)): nb = data[i].find_element_by_class_name("playlist__other").text.replace('播放量:', '').replace(' ', '') print(nb) if '万' in nb and float(nb.split("万")[0]) > 500: msk = data[i].find_element_by_css_selector("a.js_playlist") writer.writerow([msk.get_attribute("title"), nb, msk.get_attribute("href")]) if max_num != 0 and count < max_num: count += 1 else: url = 'javascript:void(0)' except Exception: print('Error') csv_file.close()