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.定位“下一页”元素

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

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

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

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

# 第一页对应的li标签
# 
  • 下一页
  • # 第二页对应的li标签 #
  • 下一页
  • # 最后一页对应的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实现数据爬取并保存_第1张图片

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

    
    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实现数据爬取并保存_第2张图片

    • 导入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实现数据爬取并保存_第3张图片
    Selenium+WebDriver+MongoDB实现数据爬取并保存_第4张图片

    你可能感兴趣的:(python,selenium,mongodb)