相对于其他静态网页常规爬虫,iframe嵌入式导致我们无法直接获取iframe内的数据,因此,我使用了seleinum中的.
switch_to.frame()方法 直接定位到对应的iframe内,便可以直接爬取数据了。
下面我就直接展示全部代码了,主要逻辑思维,我都有注释:
# author:aspiring
from selenium import webdriver
import json
class Music163_Spider:
def __init__(self):
self.start_url = "https://music.163.com/#/discover/toplist" #1.start_url
self.driver = webdriver.Chrome() # 实例化一个浏览器
def get_content_list(self): #3.提取数据
li_list = self.driver.find_elements_by_xpath("//tbody/tr")
content_list = []
for li in li_list:
item = {}
item["num"] = li.find_element_by_xpath(".//span[@class='num']").text
item["songer"] = li.find_element_by_xpath(".//div[@class='text']").get_attribute("title")
item["song"] = li.find_element_by_xpath(".//b").get_attribute("title")
item["song_time"] = li.find_element_by_xpath(".//span[@class='u-dur ']").text
print(item)
content_list.append(item)
return content_list
def save_content_list(self, content_list): #4.保存
with open("files/music163.txt", "w", encoding="utf-8") as f:
for content in content_list:
f.write(json.dumps(content, ensure_ascii=False, indent=2))
f.write("\n")
print("保存成功")
def run(self): # 实现主要逻辑
# 1.start_url
# 2.发送请求,获取响应
self.driver.get(self.start_url)
self.driver.switch_to.frame("g_iframe") # 切换到iframe
# 3.提取数据
content_list = self.get_content_list()
# 4.保存
self.save_content_list(content_list)
# 退出实例浏览器
self.driver.quit()
if __name__ == '__main__':
music163 = Music163_Spider()
music163.run()
而实现的爬取iframe内的数据中重要的一点便是,在#2.发送请求,获取响应之后,要切换到iframe内,然后再执行#3.提取数据
# 2.发送请求,获取响应
self.driver.get(self.start_url)
self.driver.switch_to.frame("g_iframe") # 切换到iframe (括号内为id属性)
# 3.提取数据
content_list = self.get_content_list()