照葫芦画瓢之python爬虫系列----(2)初次爬取简单的动态网页数据(网易、QQ音乐排行榜)

感谢提供素材的同学,无论好坏,高低,我都真心佩服你:参考文章地址: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)

结果:

<http.client.HTTPResponse object at 0x000001ADFBE16198>

很明显,我们按照这种方法是没有办法拿到源代码的,

照葫芦画瓢之python爬虫系列----(2)初次爬取简单的动态网页数据(网易、QQ音乐排行榜)

现在的问题就是:我们获取不到源代码。我们也发现问题是:网站的HTML页面没有运行javaScript,那我们的问题是让我们爬取的html页面运行javaScript即可。


文章中的解决方法是 Selenium + PhantomJS (因为时代的变迁,PhantomJS已经不被selenium所支持)


我的解决方法是:Selenium + ChromeDriver


selenium是一款十分神奇的工具--------作者(我)这样觉得

使用selenium需要自己去下载,如果是基于pycharm开发,那么可以使用File-->settings

照葫芦画瓢之python爬虫系列----(2)初次爬取简单的动态网页数据(网易、QQ音乐排行榜)

来添加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音乐榜单

在写完爬取网易云的歌单后,有些心痒痒的,于是决定爬取一下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()

如果觉得本文对你有所帮助,我深感开心。