引入

今日概要

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

知识点回顾

  • 验证码处理流程

今日详情

动态数据加载处理

一.图片懒加载

  • 什么是图片懒加载?

    • 案例分析:抓取站长素材http://sc.chinaz.com/中的图片数据

      1. #!/usr/bin/env python
      2. # -*- coding:utf-8 -*-
      3. import requests
      4. from lxml import etree
      5. if __name__ == "__main__":
      6. url = 'http://sc.chinaz.com/tupian/gudianmeinvtupian.html'
      7. headers = {
      8. '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',
      9. }
      10. #获取页面文本数据
      11. response = requests.get(url=url,headers=headers)
      12. response.encoding = 'utf-8'
      13. page_text = response.text
      14. #解析页面数据(获取页面中的图片链接)
      15. #创建etree对象
      16. tree = etree.HTML(page_text)
      17. div_list = tree.xpath('//div[@id="container"]/div')
      18. #解析获取图片地址和图片的名称
      19. for div in div_list:
      20. image_url = div.xpath('.//img/@src')
      21. image_name = div.xpath('.//img/@alt')
      22. print(image_url) #打印图片链接
      23. print(image_name)#打印图片名称

    • - 运行结果观察发现,我们可以获取图片的名称,但是链接获取的为空,检查后发现xpath表达式也没有问题,究其原因出在了哪里呢?

    • 图片懒加载概念:

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

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

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

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

      1. #!/usr/bin/env python
      2. # -*- coding:utf-8 -*-
      3. import requests
      4. from lxml import etree
      5. if __name__ == "__main__":
      6. url = 'http://sc.chinaz.com/tupian/gudianmeinvtupian.html'
      7. headers = {
      8. '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',
      9. }
      10. #获取页面文本数据
      11. response = requests.get(url=url,headers=headers)
      12. response.encoding = 'utf-8'
      13. page_text = response.text
      14. #解析页面数据(获取页面中的图片链接)
      15. #创建etree对象
      16. tree = etree.HTML(page_text)
      17. div_list = tree.xpath('//div[@id="container"]/div')
      18. #解析获取图片地址和图片的名称
      19. for div in div_list:
      20. image_url = div.xpath('.//img/@src2') #src2伪属性
      21. image_name = div.xpath('.//img/@alt')
      22. print(image_url) #打印图片链接
      23. print(image_name)#打印图片名称

简介

selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器

环境安装

  • 下载安装selenium:pip install selenium
  • 下载浏览器驱动程序:
    • http://chromedriver.storage.googleapis.com/index.html
  • 查看驱动和浏览器版本的映射关系:
    • http://blog.csdn.net/huilan_same/article/details/51896672

简单使用/效果展示

  1. from selenium import webdriver
  2. from time import sleep
  3. # 后面是你的浏览器驱动位置,记得前面加r'','r'是防止字符转义的
  4. driver = webdriver.Chrome(r'驱动程序路径')
  5. # 用get打开百度页面
  6. driver.get("http://www.baidu.com")
  7. # 查找页面的“设置”选项,并进行点击
  8. driver.find_elements_by_link_text('设置')[0].click()
  9. sleep(2)
  10. # # 打开设置后找到“搜索设置”选项,设置为每页显示50条
  11. driver.find_elements_by_link_text('搜索设置')[0].click()
  12. sleep(2)
  13. # 选中每页显示50条
  14. m = driver.find_element_by_id('nr')
  15. sleep(2)
  16. m.find_element_by_xpath('//*[@id="nr"]/option[3]').click()
  17. m.find_element_by_xpath('.//option[3]').click()
  18. sleep(2)
  19. # 点击保存设置
  20. driver.find_elements_by_class_name("prefpanelgo")[0].click()
  21. sleep(2)
  22. # 处理弹出的警告页面 确定accept() 和 取消dismiss()
  23. driver.switch_to_alert().accept()
  24. sleep(2)
  25. # 找到百度的输入框,并输入 美女
  26. driver.find_element_by_id('kw').send_keys('美女')
  27. sleep(2)
  28. # 点击搜索按钮
  29. driver.find_element_by_id('su').click()
  30. sleep(2)
  31. # 在打开的页面中找到“Selenium - 开源中国社区”,并打开这个页面
  32. driver.find_elements_by_link_text('美女_百度图片')[0].click()
  33. sleep(3)
  34. # 关闭浏览器
  35. driver.quit()

浏览器创建

Selenium支持非常多的浏览器,如Chrome、Firefox、Edge等,还有Android、BlackBerry等手机端的浏览器。另外,也支持无界面浏览器PhantomJS。

  1. from selenium import webdriver
  2. browser = webdriver.Chrome()
  3. browser = webdriver.Firefox()
  4. browser = webdriver.Edge()
  5. browser = webdriver.PhantomJS()
  6. browser = webdriver.Safari()

元素定位

webdriver 提供了一系列的元素定位方法,常用的有以下几种:

  1. find_element_by_id()
  2. find_element_by_name()
  3. find_element_by_class_name()
  4. find_element_by_tag_name()
  5. find_element_by_link_text()
  6. find_element_by_partial_link_text()
  7. find_element_by_xpath()
  8. find_element_by_css_selector()

注意

1、find_element_by_xxx找的是第一个符合条件的标签,find_elements_by_xxx找的是所有符合条件的标签。

2、根据ID、CSS选择器和XPath获取,它们返回的结果完全一致。

3、另外,Selenium还提供了通用方法find_element(),它需要传入两个参数:查找方式By和值。实际上,它就是find_element_by_id()这种方法的通用函数版本,比如find_element_by_id(id)就等价于find_element(By.ID, id),二者得到的结果完全一致。

节点交互

Selenium可以驱动浏览器来执行一些操作,也就是说可以让浏览器模拟执行一些动作。比较常见的用法有:输入文字时用send_keys()方法,清空文字时用clear()方法,点击按钮时用click()方法。示例如下:

  1. from selenium import webdriver
  2. import time
  3. browser = webdriver.Chrome()
  4. browser.get('https://www.taobao.com')
  5. input = browser.find_element_by_id('q')
  6. input.send_keys('MAC')
  7. time.sleep(1)
  8. input.clear()
  9. input.send_keys('IPhone')
  10. button = browser.find_element_by_class_name('btn-search')
  11. button.click()
  12. browser.quit()

动作链

在上面的实例中,一些交互动作都是针对某个节点执行的。比如,对于输入框,我们就调用它的输入文字和清空文字方法;对于按钮,就调用它的点击方法。其实,还有另外一些操作,它们没有特定的执行对象,比如鼠标拖曳、键盘按键等,这些动作用另一种方式来执行,那就是动作链。

比如,现在实现一个节点的拖曳操作,将某个节点从一处拖曳到另外一处,可以这样实现:

  1. from selenium import webdriver
  2. from selenium.webdriver import ActionChains
  3. import time
  4. browser = webdriver.Chrome()
  5. url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
  6. browser.get(url)
  7. browser.switch_to.frame('iframeResult')
  8. source = browser.find_element_by_css_selector('#draggable')
  9. target = browser.find_element_by_css_selector('#droppable')
  10. actions = ActionChains(browser)
  11. # actions.drag_and_drop(source, target)
  12. # actions.perform() #执行动作链
  13. actions.click_and_hold(source)
  14. time.sleep(3)
  15. for i in range(5):
  16. actions.move_by_offset(xoffset=17,yoffset=0).perform()
  17. time.sleep(0.5)
  18. actions.release()

执行JavaScript

对于某些操作,Selenium API并没有提供。比如,下拉进度条,它可以直接模拟运行JavaScript,此时使用execute_script()方法即可实现,代码如下:

  1. from selenium import webdriver
  2. browser = webdriver.Chrome()
  3. browser.get('https://www.jd.com/')
  4. browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
  5. browser.execute_script('alert("123")')

获取页面源码数据

通过page_source属性可以获取网页的源代码,接着就可以使用解析库(如正则表达式、Beautiful Soup、pyquery等)来提取信息了。

前进和后退 

  1. #模拟浏览器的前进后退
  2. import time
  3. from selenium import webdriver
  4. browser=webdriver.Chrome()
  5. browser.get('https://www.baidu.com')
  6. browser.get('https://www.taobao.com')
  7. browser.get('http://www.sina.com.cn/')
  8. browser.back()
  9. time.sleep(10)
  10. browser.forward()
  11. browser.close()

Cookie处理

使用Selenium,还可以方便地对Cookies进行操作,例如获取、添加、删除Cookies等。示例如下:

  1. from selenium import webdriver
  2. browser = webdriver.Chrome()
  3. browser.get('https://www.zhihu.com/explore')
  4. print(browser.get_cookies())
  5. browser.add_cookie({'name': 'name', 'domain': 'www.zhihu.com', 'value': 'germey'})
  6. print(browser.get_cookies())
  7. browser.delete_all_cookies()
  8. print(browser.get_cookies())

异常处理

  1. from selenium import webdriver
  2. from selenium.common.exceptions import TimeoutException,NoSuchElementException,NoSuchFrameException
  3. try:
  4. browser=webdriver.Chrome()
  5. browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
  6. browser.switch_to.frame('iframssseResult')
  7. except TimeoutException as e:
  8. print(e)
  9. except NoSuchFrameException as e:
  10. print(e)
  11. finally:
  12. browser.close()

phantomJS

PhantomJS是一款无界面的浏览器,其自动化操作流程和上述操作谷歌浏览器是一致的。由于是无界面的,为了能够展示自动化操作流程,PhantomJS为用户提供了一个截屏的功能,使用save_screenshot函数实现。

  1. from selenium import webdriver
  2. import time
  3. # phantomjs路径
  4. path = r'PhantomJS驱动路径'
  5. browser = webdriver.PhantomJS(path)
  6. # 打开百度
  7. url = 'http://www.baidu.com/'
  8. browser.get(url)
  9. time.sleep(3)
  10. browser.save_screenshot(r'phantomjs\baidu.png')
  11. # 查找input输入框
  12. my_input = browser.find_element_by_id('kw')
  13. # 往框里面写文字
  14. my_input.send_keys('美女')
  15. time.sleep(3)
  16. #截屏
  17. browser.save_screenshot(r'phantomjs\meinv.png')
  18. # 查找搜索按钮
  19. button = browser.find_elements_by_class_name('s_btn')[0]
  20. button.click()
  21. time.sleep(3)
  22. browser.save_screenshot(r'phantomjs\show.png')
  23. time.sleep(3)
  24. browser.quit()

谷歌无头浏览器

由于PhantomJs最近已经停止了更新和维护,所以推荐大家可以使用谷歌的无头浏览器,是一款无界面的谷歌浏览器。

  1. from selenium import webdriver
  2. from selenium.webdriver.chrome.options import Options
  3. import time
  4. # 创建一个参数对象,用来控制chrome以无界面模式打开
  5. chrome_options = Options()
  6. chrome_options.add_argument('--headless')
  7. chrome_options.add_argument('--disable-gpu')
  8. # 驱动路径
  9. path = r'C:\Users\ZBLi\Desktop\1801\day05\ziliao\chromedriver.exe'
  10. # 创建浏览器对象
  11. browser = webdriver.Chrome(executable_path=path, chrome_options=chrome_options)
  12. # 上网
  13. url = 'http://www.baidu.com/'
  14. browser.get(url)
  15. time.sleep(3)
  16. browser.save_screenshot('baidu.png')
  17. browser.quit()

登录qq空间,爬取数据

  1. import requests
  2. from selenium import webdriver
  3. from lxml import etree
  4. import time
  5. driver = webdriver.Chrome(executable_path='/Users/bobo/Desktop/chromedriver')
  6. driver.get('https://qzone.qq.com/')
  7. #在web 应用中经常会遇到frame 嵌套页面的应用,使用WebDriver 每次只能在一个页面上识别元素,对于frame 嵌套内的页面上的元素,直接定位是定位是定位不到的。这个时候就需要通过switch_to_frame()方法将当前定位的主体切换了frame 里。
  8. driver.switch_to.frame('login_frame')
  9. driver.find_element_by_id('switcher_plogin').click()
  10. #driver.find_element_by_id('u').clear()
  11. driver.find_element_by_id('u').send_keys('328410948') #这里填写你的QQ号
  12. #driver.find_element_by_id('p').clear()
  13. driver.find_element_by_id('p').send_keys('xxxxxx') #这里填写你的QQ密码
  14. driver.find_element_by_id('login_button').click()
  15. time.sleep(2)
  16. driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
  17. time.sleep(2)
  18. driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
  19. time.sleep(2)
  20. driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
  21. time.sleep(2)
  22. page_text = driver.page_source
  23. tree = etree.HTML(page_text)
  24. #执行解析操作
  25. li_list = tree.xpath('//ul[@id="feed_friend_list"]/li')
  26. for li in li_list:
  27. text_list = li.xpath('.//div[@class="f-info"]//text()|.//div[@class="f-info qz_info_cut"]//text()')
  28. text = ''.join(text_list)
  29. print(text+'\n\n\n')
  30. driver.close()

尽可能多的爬取豆瓣网中的电影信息

  1. from selenium import webdriver
  2. from time import sleep
  3. import time
  4. if __name__ == '__main__':
  5. url = 'https://movie.douban.com/typerank?type_name=%E6%81%90%E6%80%96&type=20&interval_id=100:90&action='
  6. # 发起请求前,可以让url表示的页面动态加载出更多的数据
  7. path = r'C:\Users\Administrator\Desktop\爬虫授课\day05\ziliao\phantomjs-2.1.1-windows\bin\phantomjs.exe'
  8. # 创建无界面的浏览器对象
  9. bro = webdriver.PhantomJS(path)
  10. # 发起url请求
  11. bro.get(url)
  12. time.sleep(3)
  13. # 截图
  14. bro.save_screenshot('1.png')
  15. # 执行js代码(让滚动条向下偏移n个像素(作用:动态加载了更多的电影信息))
  16. js = 'window.scrollTo(0,document.body.scrollHeight)'
  17. bro.execute_script(js) # 该函数可以执行一组字符串形式的js代码
  18. time.sleep(2)
  19. bro.execute_script(js) # 该函数可以执行一组字符串形式的js代码
  20. time.sleep(2)
  21. bro.save_screenshot('2.png')
  22. time.sleep(2)
  23. # 使用爬虫程序爬去当前url中的内容
  24. html_source = bro.page_source # 该属性可以获取当前浏览器的当前页的源码(html)
  25. with open('./source.html', 'w', encoding='utf-8') as fp:
  26. fp.write(html_source)
  27. bro.quit()

selenium规避被检测识别

现在不少大网站有对selenium采取了监测机制。比如正常情况下我们用浏览器访问淘宝等网站的 window.navigator.webdriver的值为 
undefined。而使用selenium访问则该值为true。那么如何解决这个问题呢?

只需要设置Chromedriver的启动参数即可解决问题。在启动Chromedriver之前,为Chrome开启实验性功能参数excludeSwitches,它的值为['enable-automation'],完整代码如下:

  1. from selenium.webdriver import Chrome
  2. from selenium.webdriver import ChromeOptions
  3. option = ChromeOptions()
  4. option.add_experimental_option('excludeSwitches', ['enable-automation'])
  5. driver = Chrome(options=option)

作业

  • 爬取网易新闻国内板块下的新闻标题和新闻内容

08.Python网络爬虫之图片懒加载技术、selenium和PhantomJS的更多相关文章

  1. Python网络爬虫之图片懒加载技术、selenium和PhantomJS

    引入 图片懒加载 selenium phantomJs 谷歌无头浏览器 知识点回顾 验证码处理流程 动态数据加载处理 一.图片懒加载 什么是图片懒加载? 案例分析:抓取站长素材http://sc.ch ...

  2. python爬虫之图片懒加载、selenium和phantomJS

    一.什么是图片懒加载 在网页中,常常需要用到图片,而图片需要消耗较大的流量.正常情况下,浏览器会解析整个HTML代码,然后从上到下依次加载<img src="xxx"> ...

  3. 爬虫之图片懒加载技术、selenium和PhantomJS

    爬虫之图片懒加载技术.selenium和PhantomJS   图片懒加载 selenium phantomJs 谷歌无头浏览器 一.图片懒加载 什么是图片懒加载? 案例分析:抓取站长素材http:/ ...

  4. 爬虫之图片懒加载技术、selenium工具与PhantomJS无头浏览器

    图片懒加载技术 selenium爬虫简单使用 2.1 selenium简介 2.2 selenium安装 2.3 selenium简单使用 2.3.1 selenium使用案例 2.3.2 selen ...

  5. Python爬虫之图片懒加载技术、selenium和PhantomJS

    一.引入 2.概要 图片懒加载 selenium phantomJs 谷歌无头浏览器 3.回顾 验证码处理流程 一.今日详情 动态数据加载处理 1.图片懒加载 什么是图片懒加载? 案例分析:抓取站长素 ...

  6. 爬虫之图片懒加载技术及js加密

    图片懒加载 图片懒加载概念: 图片懒加载是一种网页优化技术.图片作为一种网络资源,在被请求时也与普通静态资源一样,将占用网络资源,而一次性将整个页面的所有图片加载完,将大大增加页面的首屏加载时间.为了 ...

  7. 图片懒加载,Selenium,PhantomJS

    引入 今日概要 图片懒加载 selenium phantomJs 谷歌无头浏览器 知识点回顾 验证码处理流程 今日详情 动态数据加载处理 一.图片懒加载 什么是图片懒加载? 案例分析:抓取站长素材ht ...

  8. 图片懒加载、selenium和PhantomJS

    1.图片懒加载 1.1 概念及实现原理 图片懒加载是一种网页优化技术.图片作为一种网络资源,在被请求时也与普通静态资源一样,将占用网络资源,而一次性将整个页面的所有图片加载完, 将大大增加页面的首屏加 ...

  9. 爬虫(七)图片懒加载技术、selenium和PhantomJS

    动态数据加载处理 一.图片懒加载 什么是图片懒加载? 案例分析:抓取站长素材http://sc.chinaz.com/中的图片数据 #!/usr/bin/env python # -*- coding ...

随机推荐

  1. TensorFlow入门(一)

    目录 TensorFlow简介 TensorFlow基本概念 Using TensorFlow Optimization & Linear Regression & Logistic ...

  2. c# 项目之间循环引用vs弹窗提醒

    circular dependencies in projects' graph ! Projects in cycle are:ProjectImp(Name:FrameWork.Entity,Pl ...

  3. VS2015 项目中 添加windows服务

    1. 在项目中添加winows服务 今天刚刚为自己的项目添加了windows服务,以服务的形式运行后台系统,为前端提供接口服务,下面说一下具体怎么为vs项目添加windows服务 2. 添加Windo ...

  4. 模块热替换 HMR

    devserver:{hot:true},既及时更新代码,样式(需配合loader)变化,自动重编译,只适用于开发环境. 入口文件中,添加监视: + if (module.hot) {+ module ...

  5. [android] 自定义广播事件

    上一节的短信拦截在4.0以上系统中无效,可以使用这种办法实现,定义一个activity,清单文件中指定主题为透明,在onCreate()方法里面直接调用finsh()方法,关掉,这样可以就可以实现了 ...

  6. 12.QT4.7.4-解决WIN平台和Linux平台中文乱码,QLineEdit右击菜单中文显示

    1.解决Win平台中文显示 1.1首先解决win平台上中文显示乱码问题 1)首先查看qt creator的编码格式 通过->编辑->选择编码 查看. 2)如果qt creator的编码格式 ...

  7. gulp解决跨域的配置文件

    //引入插件 var gulp = require('gulp'); // var Proxy = require('gulp-connect-proxy'); var connect = requi ...

  8. CSS单位【记录】

    1.长度 2.角度 3.时间 4.分辨率 5.颜色 6.函数 7.生成内容 8.图像 9.数字 1.长度 <length>:数字和单位之间没有空格,0之后的长度单位是可选的 相对长度单位 ...

  9. IDEA 代码格式化,快捷键

    一键格式化代碼: Ctrl+Alt+L 全局搜索替换:ctrl+shift+r 强大的搜索功能,shift+shift (无论您想要搜啥都能找到) ctrl+shift+R==搜索类   CTRL+N ...

  10. iOS ---------NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)

    遇到此问题的解决办法: 使用<NSURLSessionDelegate>中的didReceiveChallenge方法,方法中的代码如下: - (void)URLSession:(NSUR ...