Selenium+WebDriver+MongoDB实现数据爬取并保存

Selenium是自动化测试常用的实现模块,但其的应用不仅仅局限在于自动化测试,这里介绍Selenium+WebDriver实现数据爬取。

需求分析

1.使用Selenium+WebDriver访问斗鱼平台英雄联盟页面,爬取当前所有直播用户的房间名和观众人数。

2.使用MongoDB实现所爬取数据的保存。

页面分析

  • 创建一个douyuSpider.py的文件,导入selenium模块并实例化一个webdriver对象。
from selenium import webdriver

driver = webdriver.Chrome()
  • 定义斗鱼英雄联盟专区的url,访问该链接。
driver .get("https://www.douyu.com/g_LOL")
# 最大化窗口
driver.maximize_window()
  • 对必要元素进行定位。

    1.定位直播房间名元素

    2.定位观众人数元素

    3.定位“下一页”元素

Selenium+WebDriver+MongoDB实现数据爬取并保存

#  定位到直播房间名在class="layout-Cover-list"的一个子孙标签h3里 names = driver.find_elements_by_xpath('//ul[@class="layout-Cover-list"]//h3') 
# 这个names是一个列表,里面的内容是该页面所有直播用户房间名所对应的标签元素

Selenium+WebDriver+MongoDB实现数据爬取并保存

# 定位到观众人数在class="DyListCover-hot"的span标签里
numbers = driver.find_elements_by_xpath('//span[@class="DyListCover-hot"]')
# 这个numbers是一个列表,里面的内容是该页面所有直播用户观众数量所对应的标签元素

Selenium+WebDriver+MongoDB实现数据爬取并保存

# 定位到下一页在class="dy-Pagination-next"的li标签里 
driver.find_element_by_class_name('dy-Pagination-next').click()

我们想通过循环来不断点击下一页来获取各个页面的数据,那么如何判定循环结束呢?不妨把关注点放在下一页定位到的那个li标签上。

# 第一页对应的li标签
# <li title="下一页" tabindex="0" class=" dy-Pagination-next" aria-disabled="false"><span class="dy-Pagination-item-custom">下一页</span></li>
# 第二页对应的li标签
# <li title="下一页" tabindex="0" class=" dy-Pagination-next" aria-disabled="false"><span class="dy-Pagination-item-custom">下一页</span></li>
# 最后一页对应的li标签
# <li title="下一页" class="dy-Pagination-disabled dy-Pagination-next" aria-disabled="true"><span class="dy-Pagination-item-custom">下一页</span></li>

我们会惊喜地发现li标签的aria-disabled属性值从false变为了true,可以以此为标志作为循环的结束。

# 循环结束的标志为
driver.find_element_by_class_name('dy-Pagination-next').get_attribute("aria-disabled") != 'false'
# .get_attribute("属性")可以获取属性对应的值

函数封装

上面的分析可以分为三部分,我们可以对其进行一下简单的封装,使代码更加清晰。

# 请求访问
def get_url():  
	driver = webdriver.Chrome()    
	driver.maximize_window()    
	driver.get("https://www.douyu.com/g_LOL")    
	sleep(1)    # 设置1秒等待,用于加载元素,避免获取不到定位元素    
	return driver
  
  # 打印单页
def print_onepage(driver):
    titles = driver.find_elements_by_xpath('//ul[@class="layout-Cover-list"]//h3')    
    numbers = driver.find_elements_by_xpath('//span[@class="DyListCover-hot"]')    
    for title,number in zip(titles,numbers):        
        print(u"观众人数:"+number.text.strip()+u"\t房间名:"+title.text.strip())
    
# 循环打印
def print_allpage(driver):    
    while driver.find_element_by_class_name('dy-Pagination-next').get_attribute("aria-disabled") == 'false':        
        print_onepage(driver)        
        driver.find_element_by_class_name('dy-Pagination-next').click()        
        sleep(1)
    driver.quit()

查看打印效果

我们先导入对应的库,打印单页看看效果是否符合预期。


from selenium import webdriverfrom time 
import sleep
def get_url():    
	driver = webdriver.Chrome()    
	driver.maximize_window()    
	driver.get("https://www.douyu.com/g_LOL")    
	sleep(1)    # 设置1秒等待,用于加载元素,避免获取不到定位元素
    return driver
def print_onepage(driver):    
	titles = driver.find_elements_by_xpath('//ul[@class="layout-Cover-list"]//h3')    
	numbers = driver.find_elements_by_xpath('//span[@class="DyListCover-hot"]')    
	for title,number in zip(titles,numbers):        
		print(u"观众人数:"+number.text.strip()+u"\t房间名:"+title.text.strip())    
	driver.quit()
    
    
if __name__ == "__main__":    
	driver = get_url()    
    print_onepage(driver)

Selenium+WebDriver+MongoDB实现数据爬取并保存

显然,打印结果是符合预期的。现在可以尝试打印所有页面。


from selenium import webdriver
from time import sleep
def get_url():    
	driver = webdriver.Chrome()    
	driver.maximize_window()    
	driver.get("https://www.douyu.com/g_LOL")    
	sleep(2)    # 设置1秒等待,用于加载元素,避免获取不到定位元素    
	return driver
def print_onepage(driver):    
	titles = driver.find_elements_by_xpath('//ul[@class="layout-Cover-list"]//h3')    
	numbers = driver.find_elements_by_xpath('//span[@class="DyListCover-hot"]')    
	for title,number in zip(titles,numbers):        
		print(u"观众人数:"+number.text.strip()+u"\t房间名:"+title.text.strip())
def print_allpage(driver):    
	while driver.find_element_by_class_name('dy-Pagination-next').get_attribute("aria-disabled") == 'false':        
		print_onepage(driver)        
        driver.find_element_by_class_name('dy-Pagination-next').click()        
		sleep(1)    
	driver.quit()
  
if __name__ == "__main__":    
    driver = get_url()    
    print_allpage(driver)

保存数据

这里使用pymongo模块将数据保存到MongoDB数据库。

  • 使用mongo在命令行打开数据库,查看端口地址。

Selenium+WebDriver+MongoDB实现数据爬取并保存

  • 导入pymongo模块,并实例化数据库。
import pymongo


client = pymongo.MongoClient('mongodb://127.0.0.1:27017')# 端口地址
collection = client["douyu"]["LOL"]  # 建立一个douyu的库,并在其下面建立一个叫LOL的集合
  • 保存数据到MongoDB数据库。
def store_onepage(i,driver):    
    titles = driver.find_elements_by_xpath('//ul[@class="layout-Cover-list"]//h3')    
    numbers = driver.find_elements_by_xpath('//span[@class="DyListCover-hot"]')    
    for title,number in zip(titles,numbers):        
        # print(u"观众人数:"+number.text.strip()+u"\t房间名:"+title.text.strip())        
        data = {}        
        data['观众人数'] = number.text.strip()        
        data['房间名'] = title.text.strip()        
		collection.insert_one(data)    
    print("第%d页保存完毕!"%i)
    
def store_allpage(driver):    
	i = 1    
	while driver.find_element_by_class_name('dy-Pagination-next').get_attribute("aria-disabled") == 'false':        
		store_onepage(i,driver)        
		i += 1        
		driver.find_element_by_class_name('dy-Pagination-next').click()        
		sleep(1)    
	driver.quit()
  • 完整代码
import pymongo
from selenium import webdriver
from time import sleep

client = pymongo.MongoClient('mongodb://127.0.0.1:27017')# 端口地址
collection = client["douyu"]["LOL"]  # 建立一个douyu的库,并在其下面建立一个叫LOL的集合

def store_onepage(i,driver):    
    titles = driver.find_elements_by_xpath('//ul[@class="layout-Cover-list"]//h3')    
    numbers = driver.find_elements_by_xpath('//span[@class="DyListCover-hot"]')    
    for title,number in zip(titles,numbers):        
        # print(u"观众人数:"+number.text.strip()+u"\t房间名:"+title.text.strip())        
        data = {}        
        data['观众人数'] = number.text.strip()        
        data['房间名'] = title.text.strip()        
		collection.insert_one(data)    
    print("第%d页保存完毕!"%i)
    
def store_allpage(driver):    
	i = 1    
	while driver.find_element_by_class_name('dy-Pagination-next').get_attribute("aria-disabled") == 'false':        
		store_onepage(i,driver)        
		i += 1        
		driver.find_element_by_class_name('dy-Pagination-next').click()        
		sleep(1)    
	driver.quit()

if __name__ == "__main__":    
	driver = get_url()    
	store_allpage(driver)
  • 保存效果展示

Selenium+WebDriver+MongoDB实现数据爬取并保存
Selenium+WebDriver+MongoDB实现数据爬取并保存

上一篇:Python_字符串之删除空白字符或某字符或字符串


下一篇:AI渐变网格绘制时尚漂亮的红玫瑰花及花瓶