Python爬虫图片懒加载技术 selenium和PhantomJS解析


Posted in Python onSeptember 18, 2019

一.什么是图片懒加载?

- 案例分析:抓取站长素材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这个伪属性中

#!/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'2) #src2伪属性
     image_name = div.xpath('.//img/@alt')
     print(image_url) #打印图片链接
     print(image_name)#打印图片名称

二.selenium

- 什么是selenium?

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

- 环境搭建

1.安装selenum:pip install selenium

2.获取某一款浏览器的驱动程序(以谷歌浏览器为例) 

2.1 谷歌浏览器驱动下载地址

2.2 下载的驱动程序必须和浏览器的版本统一

大家可以根据http://blog.csdn.net/huilan_same/article/details/51896672中提供的版本映射表进行对应

- 效果展示:大家可以将如下代码运行,观看效果

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名字查找

三.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'phantomjs\baidu.png')
# 查找input输入框
my_input = browser.find_element_by_id('kw')
# 往框里面写文字
my_input.send_keys('美女')
time.sleep(3)
#截屏
browser.save_screenshot(r'phantomjs\meinv.png')
# 查找搜索按钮
button = browser.find_elements_by_class_name('s_btn')[0]
button.click()
time.sleep(3)
browser.save_screenshot(r'phantomjs\show.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:\Users\Administrator\Desktop\爬虫授课\day05\ziliao\phantomjs-2.1.1-windows\bin\phantomjs.exe'
  # 创建无界面的浏览器对象
  bro = webdriver.PhantomJS(path)
  # 发起url请求
  bro.get(url)
  time.sleep(3)
  # 截图
  bro.save_screenshot('1.png')

  # 执行js代码(让滚动条向下偏移n个像素(作用:动态加载了更多的电影信息))
  js = 'document.body.scrollTop=2000'
  bro.execute_script(js) # 该函数可以执行一组字符串形式的js代码
  time.sleep(4)
  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:\Users\ZBLi\Desktop\1801\day05\ziliao\chromedriver.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()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python的文件操作方法汇总
Nov 10 Python
Python set常用操作函数集锦
Nov 15 Python
Python装饰器简单用法实例小结
Dec 03 Python
使用python绘制二元函数图像的实例
Feb 12 Python
在交互式环境中执行Python程序过程详解
Jul 12 Python
使用Python调取任意数字资产钱包余额功能
Aug 15 Python
Python装饰器使用你可能不知道的几种姿势
Oct 25 Python
python爬虫开发之使用Python爬虫库requests多线程抓取猫眼电影TOP100实例
Mar 10 Python
python plt可视化——打印特殊符号和制作图例代码
Apr 17 Python
Python xlrd/xlwt 创建excel文件及常用操作
Sep 24 Python
谈谈python垃圾回收机制
Sep 27 Python
Python数据模型与Python对象模型的相关总结
Jan 26 Python
python rsa实现数据加密和解密、签名加密和验签功能
Sep 18 #Python
决策树剪枝算法的python实现方法详解
Sep 18 #Python
python生成requirements.txt的两种方法
Sep 18 #Python
python2与python3爬虫中get与post对比解析
Sep 18 #Python
python中class的定义及使用教程
Sep 18 #Python
django创建超级用户过程解析
Sep 18 #Python
python实现网站微信登录的示例代码
Sep 18 #Python
You might like
php 全文搜索和替换的实现代码
2008/07/29 PHP
php设计模式 Prototype (原型模式)代码
2011/06/26 PHP
php ajax 静态分页过程形式
2011/09/02 PHP
优化WordPress中文章与评论的时间显示
2016/01/12 PHP
Laravel jwt 多表(多用户端)验证隔离的实现
2019/12/18 PHP
JSChart轻量级图形报表工具(内置函数中文参考)
2010/10/11 Javascript
js下关于onmouseout、事件冒泡的问题经验小结
2010/12/09 Javascript
基于Jquery的文字自动截取(提供源代码)
2011/08/09 Javascript
JavaScript初学者应注意的七个细节详细介绍
2012/12/27 Javascript
Javascript中获取对象的原型对象的方法小结
2015/02/25 Javascript
jquery实现清新实用的网页菜单效果
2015/08/28 Javascript
BootStrap CSS全局样式和表格样式源码解析
2017/01/20 Javascript
基于easyui checkbox 的一些操作处理方法
2017/07/10 Javascript
JavaScript数组去重的多种方法(四种)
2017/09/19 Javascript
vue多级复杂列表展开/折叠及全选/分组全选实现
2018/11/05 Javascript
Nuxt项目支持eslint+pritter+typescript的实现
2019/05/20 Javascript
Vue项目vscode 安装eslint插件的方法(代码自动修复)
2020/04/15 Javascript
简单了解JavaScript弹窗实现代码
2020/05/07 Javascript
[41:13]完美世界DOTA2联赛PWL S2 Forest vs Rebirth 第一场 11.20
2020/11/20 DOTA
详解python发送各类邮件的主要方法
2016/12/22 Python
Python基于回溯法子集树模板解决野人与传教士问题示例
2017/09/11 Python
Python自定义一个类实现字典dict功能的方法
2019/01/19 Python
实例讲解Python脚本成为Windows中运行的exe文件
2019/01/24 Python
numpy基础教程之np.linalg
2019/02/12 Python
在Pandas中处理NaN值的方法
2019/06/25 Python
树莓派安装OpenCV3完整过程的实现
2019/10/10 Python
德国团购网站:Groupon德国
2018/03/13 全球购物
在校大学生个人的自我评价
2014/02/13 职场文书
大学生演讲稿
2014/04/25 职场文书
小学校长先进事迹材料
2014/05/13 职场文书
《中国梦我的梦》中学生演讲稿
2014/08/20 职场文书
任命书怎么写
2015/03/02 职场文书
2015年人民调解工作总结
2015/05/18 职场文书
高考满分作文赏析(2篇)
2019/08/12 职场文书
Nginx服务器添加Systemd自定义服务过程解析
2021/03/31 Servers
mysql中varchar类型的日期进行比较、排序等操作的实现
2021/11/17 MySQL