zoukankan      html  css  js  c++  java
  • Python网络爬虫之图片懒加载技术、selenium和PhantomJS

    本文概要:

    • 图片懒加载
    • selenium
    • phantomJs
    • 谷歌无头浏览器

    一、图片懒加载

    什么是图片懒加载?

    • 案例分析:抓取站长素材http://sc.chinaz.com/中的图片数据
      #!/usr/bin/env python
      # -*- coding:utf-8 -*-
      import requests
      from lxml import etree
      
      if __name__ == "__main__":
           url = 'http://sc.chinaz.com/tupian/gudianmeinvtupian.html'
           headers = {
               'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
           }
           #获取页面文本数据
           response = requests.get(url=url,headers=headers)
           response.encoding = 'utf-8'
           page_text = response.text
           #解析页面数据(获取页面中的图片链接)
           #创建etree对象
           tree = etree.HTML(page_text)
           div_list = tree.xpath('//div[@id="container"]/div')
           #解析获取图片地址和图片的名称
           for div in div_list:
               image_url = div.xpath('.//img/@src')
               image_name = div.xpath('.//img/@alt')
               print(image_url) #打印图片链接
               print(image_name)#打印图片名称
    • 运行结果观察发现,我们可以获取图片的名称,但是链接获取的为空,检查后发现xpath表达式也没有问题,究其原因出在了哪里呢?

    • 图片懒加载概念:

      • 图片懒加载是一种网页优化技术。图片作为一种网络资源,在被请求时也与普通静态资源一样,将占用网络资源,而一次性将整个页面的所有图片加载完,将大大增加页面的首屏加载时间。为了解决这种问题,通过前后端配合,使图片仅在浏览器当前视窗内出现时才加载该图片,达到减少首屏图片请求数的技术就被称为“图片懒加载”。

    • 网站一般如何实现图片懒加载技术呢?

      • 在网页源码中,在img标签中首先会使用一个“伪属性”(通常使用src2,original......)去存放真正的图片链接而并非是直接存放在src属性中。当图片出现到页面的可视化区域中,会动态将伪属性替换成src属性,完成图片的加载。

    • 站长素材案例后续分析:通过细致观察页面的结构后发现,网页中图片的链接是存储在了src2这个伪属性中

    import requests
    import os
    import urllib
    from lxml import etree
    
    url = "http://sc.chinaz.com/tupian/hunsha.html"
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
    }
    if not os.path.exists('./imgs'):
        os.mkdir('./imgs')
        
    page_text = requests.get(url=url,headers=headers).text
    
    tree = etree.HTML(page_text)
    
    img_url_list = tree.xpath('//div[@id="container"]/div/div/a/img/@src | //div[@id="container"]/div/div/a/img/@src2')     #图片懒加载处理办法
    
    for img_url in img_url_list:
        imgName = img_url.split('/')[-1]
        imaPath = "./imgs/"+imgName
        urllib.request.urlretrieve(url=img_url,filename=imaPath)
    图片懒加载处理方案

    二.selenium

    • 什么是selenium?
      • 是Python的一个第三方库,对外提供的接口可以操作浏览器,然后让浏览器完成自动化的操作。  

    • 环境搭建

    • 用法展示
    from selenium import webdriver
    from time import sleep
    
    # 后面是你的浏览器驱动位置,记得前面加r'','r'是防止字符转义的
    driver = webdriver.Chrome(r'驱动程序路径')
    # 用get打开百度页面
    driver.get("http://www.baidu.com")
    # 查找页面的“设置”选项,并进行点击
    driver.find_elements_by_link_text('设置')[0].click()
    sleep(2)
    # # 打开设置后找到“搜索设置”选项,设置为每页显示50条
    driver.find_elements_by_link_text('搜索设置')[0].click()
    sleep(2)
    
    # 选中每页显示50条
    m = driver.find_element_by_id('nr')
    sleep(2)
    m.find_element_by_xpath('//*[@id="nr"]/option[3]').click()
    m.find_element_by_xpath('.//option[3]').click()
    sleep(2)
    
    # 点击保存设置
    driver.find_elements_by_class_name("prefpanelgo")[0].click()
    sleep(2)
    
    # 处理弹出的警告页面   确定accept() 和 取消dismiss()
    driver.switch_to_alert().accept()
    sleep(2)
    # 找到百度的输入框,并输入 美女
    driver.find_element_by_id('kw').send_keys('美女')
    sleep(2)
    # 点击搜索按钮
    driver.find_element_by_id('su').click()
    sleep(2)
    # 在打开的页面中找到“Selenium - 开源中国社区”,并打开这个页面
    driver.find_elements_by_link_text('美女_百度图片')[0].click()
    sleep(3)
    
    # 关闭浏览器
    driver.quit()
    • 代码流程
    #导包
    from selenium import webdriver  
    #创建浏览器对象,通过该对象可以操作浏览器
    browser = webdriver.Chrome('驱动路径')
    #使用浏览器发起指定请求
    browser.get(url)
    
    #使用下面的方法,查找指定的元素进行操作即可
        find_element_by_id            根据id找节点
        find_elements_by_name         根据name找
        find_elements_by_xpath        根据xpath查找
        find_elements_by_tag_name     根据标签名找
        find_elements_by_class_name   根据class名字查找
        find_elements_by_link_text       根据超链接文本查找

    三.phantomJs

    • PhantomJS是一款无界面的浏览器,其自动化操作流程和上述操作谷歌浏览器是一致的。由于是无界面的,为了能够展示自动化操作流程,PhantomJS为用户提供了一个截屏的功能,使用save_screenshot函数实现。
    • 用法展示
    from selenium import webdriver
    import time
    
    # phantomjs路径
    path = r'PhantomJS驱动路径'
    browser = webdriver.PhantomJS(path)
    
    # 打开百度
    url = 'http://www.baidu.com/'
    browser.get(url)
    
    time.sleep(3)
    
    browser.save_screenshot(r'phantomjsaidu.png')    #截屏
    
    # 查找input输入框
    my_input = browser.find_element_by_id('kw')
    # 往框里面写文字
    my_input.send_keys('美女')
    time.sleep(3)
    #截屏
    browser.save_screenshot(r'phantomjsmeinv.png')
    
    # 查找搜索按钮
    button = browser.find_elements_by_class_name('s_btn')[0]
    button.click()
    
    time.sleep(3)
    
    browser.save_screenshot(r'phantomjsshow.png')
    
    time.sleep(3)
    
    browser.quit()
    • 重点:selenium+phantomjs 就是爬虫终极解决方案:有些网站上的内容信息是通过动态加载js形成的,所以使用普通爬虫程序无法回去动态加载的js内容。例如豆瓣电影中的电影信息是通过下拉操作动态加载更多的电影信息。
      • 综合操作:需求是尽可能多的爬取豆瓣网中的电影信息
    from selenium import webdriver
    from time import sleep
    import time
    
    if __name__ == '__main__':
        url = 'https://movie.douban.com/typerank?type_name=%E6%81%90%E6%80%96&type=20&interval_id=100:90&action='
        # 发起请求前,可以让url表示的页面动态加载出更多的数据
        path = r'C:UsersAdministratorDesktop爬虫授课day05ziliaophantomjs-2.1.1-windowsinphantomjs.exe'
        # 创建无界面的浏览器对象
        bro = webdriver.PhantomJS(path)
        # 发起url请求
        bro.get(url)
        time.sleep(3)
        # 截图
        bro.save_screenshot('1.png')
    
        # 执行js代码(让滚动条向下偏移n个像素(作用:动态加载了更多的电影信息))
        js = 'window.scrollTo(0,document.body.scrollHeight)'
        bro.execute_script(js)  # 该函数可以执行一组字符串形式的js代码
        time.sleep(2)
    
        bro.execute_script(js)  # 该函数可以执行一组字符串形式的js代码
        time.sleep(2)
        bro.save_screenshot('2.png') 
        time.sleep(2) 
        # 使用爬虫程序爬去当前url中的内容 
        html_source = bro.page_source # 该属性可以获取当前浏览器的当前页的源码(html) 
        with open('./source.html', 'w', encoding='utf-8') as fp: 
            fp.write(html_source) 
        bro.quit()

    四.谷歌无头浏览器

    • 由于PhantomJs最近已经停止了更新和维护,所以推荐大家可以使用谷歌的无头浏览器,是一款无界面的谷歌浏览器。
    • 代码展示:
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    import time
     
    # 创建一个参数对象,用来控制chrome以无界面模式打开
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')
    # 驱动路径
    path = r'C:UsersBLiDesktop1801day05ziliaochromedriver.exe'
     
    # 创建浏览器对象
    browser = webdriver.Chrome(executable_path=path, chrome_options=chrome_options)
     
    # 上网
    url = 'http://www.baidu.com/'
    browser.get(url)
    time.sleep(3)
     
    browser.save_screenshot('baidu.png')
     
    browser.quit()
  • 相关阅读:
    otter安装、使用
    windows下xampp安装rabbitmq的PHP扩展AMQP
    CentOS7下安装RabbitMQ
    CentOS7下开放端口
    CentOS7下安装Redis
    @b.windows.last.use
    Rspec基本语法
    ruby firefox23报错:waiting for evaluate.js load failed
    notepad++上配置ruby执行环境
    cucumber的hooks
  • 原文地址:https://www.cnblogs.com/fengchong/p/10453110.html
Copyright © 2011-2022 走看看