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这个伪属性中

      #!/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的一个第三方库,对外提供的接口可以操作浏览器,然后让浏览器完成自动化的操作。  

  • 环境搭建

    • 安装selenum:pip install selenium

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

      • 谷歌浏览器驱动下载地址:http://chromedriver.storage.googleapis.com/index.html

      • 下载的驱动程序必须和浏览器的版本统一,大家可以根据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 timeif __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 = '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:\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()

作业

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

转载于:https://www.cnblogs.com/presleyren/p/10579705.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/425289.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

POJ 2299 - Ultra-QuickSort BIT

题意 给我们一个序列 序列长度小于500000 每个元素 小于999999999 让我们只移动相邻的元素 最终使得他们移动到正好上升序的最小移动次数 分析 我们看 最小的移动次数其实是个幌子 因为你移动相邻的元素 大的元素你不论如何移动 就是要一个个移动到所有比他小的元素的后面…

[Leetcode][第题][JAVA][两个数组的交集 II1][双指针][HashMap]

【问题描述】[中等] 【解答思路】 1. 哈希映射 复杂度分析 class Solution {public int[] intersect(int[] nums1, int[] nums2) {if (nums1.length > nums2.length) {return intersect(nums2, nums1);}Map<Integer, Integer> map new HashMap<Integer, Intege…

63 javabean的作用域范围

定义一个users类 package srever;public class Users {private String username;private String password;public Users() {}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword(…

【Immutable】拷贝与JSON.parse(JSON.stringify()),深度比较相等与underscore.isEqual(),性能比较...

样本&#xff1a;1MB的JSON文件&#xff0c;引入后生成500份的一个数组&#xff1b; 结果如下&#xff1a; 拷贝性能&#xff1a; JSON.parse(JSON.stringify()) 的方法&#xff1a;2523.55517578125ms immutable.fromJs: 1295.159912109375ms 快了一倍 深度比较性能&#xff1…

HDU 1566 Count the Colors 树状树组 区间更新 单点求值

#include<bits/stdc.h> using namespace std; const int lim 100010; int n,c[lim];// 记录差分变化 void update(int a,int val){while(a<n){c[a]val;aa&(-a);} } int get(int x){int sum0;while(x){sumc[x];x-x&(-x);}return sum; } int main() {while(sc…

[小技巧][JAVA][转换]List, Integer[], int[]的相互转换

int[] 转 List< Integer > int[] data {4, 5, 3, 6, 2, 5, 1}&#xff1b; List<Integer> list1 Arrays.stream(data).boxed().collect(Collectors.toList());// Arrays.stream(arr) 可以替换成IntStream.of(arr)。// 1.使用Arrays.stream将int[]转换成IntStrea…

65 modol1用户登录

定义一个Users类 package srever;public class Users {private String username;private String password;public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword() {return passwor…

[剑指offer]面试题第[58-2]题[JAVA][左旋转字符串][拼接]

【问题描述】[中等] 【解答思路】 1. 字符串切片 应用字符串切片函数&#xff0c;可方便实现左旋转字符串。 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(N) public String reverseLeftWords(String s, int n) {return s.substring(n, s.length()) s.substring(0,…

Codeforce - 920C- Swap Adjacent Elements 排序|思维

题意 输入n 再输入n个数为1~n的一种排列 再输入n-1个1或0&#xff0c;1表示该元素可以和后面的元素进行交换&#xff0c;0表示不能和后面的元素进行交换 让我们判断这个数组能否经过交换得到一个递增序列 分析 我们发现连续的1的范围内再加上后面一个0 此区间内任意一个元…

[剑指offer]面试题第[59-1]题[Leetcode][第239题][JAVA][滑动窗口的最大值][单调队列][优先队列]

【问题描述】[困难] 【解答思路】 1. 暴力 两层 for 循环&#xff0c;每次都从窗口中找最大值即可 时间复杂度&#xff1a;O(N^2) 空间复杂度&#xff1a;O(N) public int[] maxSlidingWindow(int[] nums, int k) {int n nums.length;if (n 0) {return nums;}int result[]…

Codeforce Flea CodeForces - 32C 规律|思维

题意 给我们一个n*m的表格 告诉我们每次跳跃的格子数量s 只能垂直或者水平跳跃 可以跳跃无限次 那么某格子能到达的不同格子的数量就是这个格子的值 求表格中值最大的格子的数量 分析 表面上看像是搜索 然而1e6的数据搜索行不通 其实分析下是个规律题 也就是符合能够互相抵…

视图高级

目标 限制请求method页面重定向HttpRequest 对象HttpResponse 对象生产CVS 文件类视图错误处理一 限制请求method 1-1 常用的请求method 1. GET请求&#xff1a;GET请求一般用来向服务器索取数据&#xff0c;但不会向服务器提交数据&#xff0c;不会对服务器的状态进行更改。比…

PAT1130. Infix Expression (25) 中序遍历

题意 给出一棵中缀树 然后输出他的表达式 分析 一开始还想随便在输入点中任找一个点然后不断深搜建树 后来才发现这道题输入数据就把树根据指向关系已经建立好了 只需要确定根节点然后中序遍历就好了 code #include<bits/stdc.h> using namespace std; bool bok[…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第2篇]多核处理器和向量处理器的区别

从表面看来&#xff0c;你可能很困惑着两个处理器到底有什么区别。如果你熟悉并行计算的话&#xff0c;那么你可能会碰见这两种处理器。因此它们到底有什么区别?这个就是这周的问题。在我们进入细节之前&#xff0c;为什么我们不看看这两个不同的处理器在作为并行计算一部分的…

68 cookie在登录中的作用

定义一个login.jsp页面 <% page language"java" import"java.util.*,java.net.*" contentType"text/html; charsetutf-8"%> <% String path request.getContextPath(); String basePath request.getScheme()"://"request.…

解决tfs工作区绑定问题

TFS挂掉后&#xff0c;本机代码没有移除映射(解绑)&#xff0c;导致在新的TFS无法映射到原目录&#xff0c;网上搜索了一堆都是删除cache的&#xff0c;从路径看&#xff0c;都是3.0的老版本&#xff0c;vs2015&#xff0c;vs2017&#xff0c;vs2019可用如下方法进行解绑&#…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第3篇]影响计算能力和存储能力的因素

这个是密码学52件事的第三个知识点&#xff0c;这些问题被总结成密码学博士在第一年必须要知道的事情。我们将在接下里的一年里每周讨论一个问题。我是被安排的第三个问题的学生。 问题&#xff1a;估计下面器件的相对的计算和存储能力 一个智能卡(一卡通??)微控制器(即传感…