当前位置: 首页 > news >正文

《零基础入门学习Python》第056讲:论一只爬虫的自我修养4:网络爬图

今天我们结合前面学习的知识,进行一个实例,从网络上下载图片,话说我们平时闲来无事会上煎蛋网看看新鲜事,那么,熟悉煎蛋网的朋友一定知道,这里有一个 随手拍 的栏目,我们今天就来写一个爬虫,自动抓取每天更新的 随手拍。

要写爬虫,首先要做的第一件事就是踩点,主动发现网页之间的规律,还有图片链接之间有什么规律,例如说,该网站的链接形式为:http://jandan.net/ooxx/page-‘页码数’#comments,(页码数应该小于等于当天的页码数(即目前最大页码数)),

1.那我们怎样获取目前最大的页码数呢(最新页码),我们在页码[77]这个位置点击右键,审查元素,看到了:<span class="current-comment-page">[77]</span>

我们完全可以通过搜索 current-comment-page 在后面偏移 3 位就可以得到 77 这个最新的页面,因为你不能去输入一个具体的数字,因为这里的数字每天都会改变。

2.我们在图片的位置点击右键,审查元素,发现了图片的地址,都是来自于新浪,然后都在 img 标签里,我们就可以使用 img src 作为关键词来进行查找,搜索到了图片的地址就可以参照我们之前下载一只猫的例子了。把下面图片的地址用 urlopen() 打开,然后将其 save 到一个文件里去(二进制),就可以了。

<img src="http://ww3.sinaimg.cn/mw600/006XNEY7gy1fy62ba9d6cj30u00u0x6p.jpg" style="max-width: 480px; max-height: 750px;">

我们弄清楚了以上几点,就可以开始写我们的爬虫程序啦.....

(我们抓取前10页的图片,保存到指定的本地文件夹中)

下面是老师讲的代码:

 
  1. #从煎蛋网的随手拍栏目下载图片

  2. import urllib.request

  3. import os

  4. import random

  5. def url_open(url):

  6. req = urllib.request.Request(url)

  7. req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36')

  8. #使用代理(就加入下面五行)

  9. #proxies = ['119.6.144.70:81', '111.1.36.9:80', '203.144.144.162:8080']

  10. #proxy = random.choice(proxies)

  11. #proxy_support = urllib.request.ProxyHandler({'http':proxy})

  12. #opener = urllib.request.build_opener(proxy_support)

  13. #urllib.request.install_opener(opener)

  14. response = urllib.request.urlopen(url)

  15. html = response.read()

  16. return html

  17. def get_page(url): #得到最新页面的页码数

  18. html = url_open(url)

  19. html = html.decode('utf-8') #因为要以字符串的形式查找,所以要 decode

  20. #然后就是查找 html 中的 'current-comment-page'

  21. a = html.find( 'current-comment-page') + 23 #加上 23 位偏移就刚到到页码数的第一位数字

  22. b = html.find(']', a) #找到 a 位置之后的第一个方括号所在位置的索引坐标

  23. return html[a : b] #这就是最新的页码数啦

  24. def find_imgs(url): #给一个页面的链接,返回所有图片地址组成的列表

  25. html = url_open(url).decode('utf-8')

  26. img_addrs = [] #声明一个保存图片地址的列表

  27. #查找图片地址

  28. a = html.find('img src=')

  29. while a != -1:

  30. b = html.find('.jpg', a, a+255) #在 a 到 a+255 区间找 '.jpg',防止有不是 '.jpg' 格式的图片

  31. #如果 b 找不到,b 就返回 -1

  32. if b != -1:

  33. img_addrs.append(html[a+9: b+4])

  34. else:

  35. b = a + 9

  36. a = html.find('img src=', b)

  37. return img_addrs

  38. def save_imgs(folder, img_addrs):

  39. for each in img_addrs:

  40. filename = each.split('/')[-1]

  41. with open(filename, 'wb') as f:

  42. img = url_open(each)

  43. f.write(img)

  44. def download_figures(folder = 'figures', page = 10):

  45. os.mkdir(folder) #创建文件夹

  46. os.chdir(folder)

  47. url = "http://jandan.net/ooxx/" #随手拍栏目的链接,也是最新页面的链接

  48. page_num = int(get_page(url)) #得到最新页面的页码数

  49. for i in range(page):

  50. page_url = url + 'page-' + str(page_num) + '#comments' #得到要爬取的页面的链接

  51. print(page_url)

  52. img_addrs = find_imgs(page_url) #得到页面所有图片的地址,保存为列表

  53. save_imgs(folder, img_addrs) #保存图片到本地文件夹

  54. page_num -= 1 #逐步找到前几个页面

  55. if __name__ == '__main__':

  56. download_figures()

但是现在,煎蛋网用这段代码是无法实现的了,主要问题在于 没有办法爬取到 .jpg,这是因为这个网站已经被加密了。

怎样判断一个网站被加密了,就是

使用urllib.urlopen导出html文本和审查元素中相应字段对不上。

以后你会发现对不上是常态,一般是JS加密的  可以说大一点的网站这些信息都会对不上。

那怎么解决呢?

目前我只用的一种方法就是:使用selenium爬取js加密的网页

需要详细讲解的可以查看:python使用selenium爬取js加密的网页

所以呢,我的代码就是下面这样子了:

 
  1. #从加密的煎蛋网的随手拍栏目下载图片

  2. import os

  3. from selenium import webdriver

  4. import urllib.request

  5. def url_open(url): #返回普通不加密网页的源码(速度快)

  6. req = urllib.request.Request(url)

  7. req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36')

  8. response = urllib.request.urlopen(url)

  9. html = response.read()

  10. return html

  11. def url_open_jm(url): #返回加密网页的源码(速度慢)

  12. chrome = webdriver.Chrome()

  13. chrome.get(url)

  14. html = chrome.page_source

  15. return html #返回的就是字符串

  16. '''

  17. def get_page(url): #得到最新页面的页码数(可以使用不加密读码得到,为了加快速度)

  18. html = url_open(url)

  19. #然后就是查找 html 中的 'current-comment-page'

  20. a = html.find( 'current-comment-page') + 23 #加上 23 位偏移就刚到到页码数的第一位数字

  21. b = html.find(']', a) #找到 a 位置之后的第一个方括号所在位置的索引坐标

  22. return html[a : b] #这就是最新的页码数啦

  23. '''

  24. def get_page(url): #得到最新页面的页码数

  25. html = url_open(url)

  26. html = html.decode('utf-8') #因为要以字符串的形式查找,所以要 decode

  27. #然后就是查找 html 中的 'current-comment-page'

  28. a = html.find( 'current-comment-page') + 23 #加上 23 位偏移就刚到到页码数的第一位数字

  29. b = html.find(']', a) #找到 a 位置之后的第一个方括号所在位置的索引坐标

  30. return html[a : b] #这就是最新的页码数啦

  31. def find_imgs(url): #给一个页面的链接,返回所有图片地址组成的列表

  32. html = url_open_jm(url) #这个必须使用加密打开的方式

  33. img_addrs = [] #声明一个保存图片地址的列表

  34. #查找图片地址

  35. #加密的网页破解后得到的图像在这里:

  36. #<img src="http://ww3.sinaimg.cn/mw600/006XNEY7gy1fy66dacugfj30qh0zkdhu.jpg"

  37. #所以要先找jpg,然后找img src=

  38. a = html.find('.jpg')

  39. while a != -1:

  40. b = html.rfind('img src=', a-100, a) #在 a-100 到 a区间找 'img src=',必须反向查找

  41. #如果 b 找不到,b 就返回 -1

  42. if b != -1:

  43. img_addrs.append(html[b+9: a+4])

  44. a = html.find('.jpg', a+4)

  45. for each in img_addrs:

  46. print(each)

  47. return img_addrs

  48. def save_imgs(folder, img_addrs):

  49. for each in img_addrs:

  50. filename = each.split('/')[-1]

  51. with open(filename, 'wb') as f:

  52. img = url_open(each)

  53. f.write(img)

  54. def download_figures(folder = 'figures', page = 2):

  55. os.mkdir(folder) #创建文件夹

  56. os.chdir(folder)

  57. url = "http://jandan.net/ooxx/" #随手拍栏目的链接,也是最新页面的链接

  58. page_num = int(get_page(url)) #得到最新页面的页码数

  59. for i in range(page):

  60. page_url = url + 'page-' + str(page_num) + '#comments' #得到要爬取的页面的链接

  61. print(page_url)

  62. img_addrs = find_imgs(page_url) #得到页面所有图片的地址,保存为列表

  63. save_imgs(folder, img_addrs) #保存图片到本地文件夹

  64. page_num -= 1 #逐步找到前几个页面

  65. if __name__ == '__main__':

  66. download_figures()

完美实现目标,只不过selenium 的速度是真的慢,以后如果有更好的办法,会继续改进的,也希望大家多多批评指导。

相关文章:

《零基础入门学习Python》第056讲:论一只爬虫的自我修养4:网络爬图

今天我们结合前面学习的知识&#xff0c;进行一个实例&#xff0c;从网络上下载图片&#xff0c;话说我们平时闲来无事会上煎蛋网看看新鲜事&#xff0c;那么&#xff0c;熟悉煎蛋网的朋友一定知道&#xff0c;这里有一个 随手拍 的栏目&#xff0c;我们今天就来写一个爬虫&…...

23.7.26总结(博客项目)

接下来要完成&#xff1a; 从主页面点击进入时&#xff0c;通过作者id从数据库查找作者的nickname点击文章收藏&#xff08;需要有收藏列表&#xff09;首页还要加最新发布&#xff0c;点赞收藏最多作者名得改成文章作者&#xff08;通过user_id从user表中拿数据&#xff09;消…...

安全第一天

1. 编码 1.1 ASCLL编码 ASCII 是基于拉丁字母的一套电脑编码系统&#xff0c;主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准&#xff0c;并等同于国际标准ISO/IEC 646。 1.2 URL编码 URL&#xff1a;&#xff08;统一资源定位器、定位地址&#xff0c;俗称网页…...

SpringCloud学习路线(12)——分布式搜索ElasticSeach数据聚合、自动补全、数据同步

一、数据聚合 聚合&#xff08;aggregations&#xff09;&#xff1a; 实现对文档数据的统计、分析、运算。 &#xff08;一&#xff09;聚合的常见种类 桶&#xff08;Bucket&#xff09;聚合&#xff1a; 用来做文档分组。 TermAggregation&#xff1a; 按照文档字段值分组…...

cloudstack的PlugNicCommand的作用

PlugNicCommand是CloudStack中的一个命令&#xff0c;用于将一个网络接口卡&#xff08;NIC&#xff09;插入到虚拟机实例中。它的作用是将一个已存在的NIC连接到指定的虚拟机&#xff0c;以扩展虚拟机的网络功能。 具体来说&#xff0c;PlugNicCommand可以完成以下几个步骤&a…...

LT9211C 是一款MIPI/RGB/2PORT LVDS互转的芯片

LT9211C 1.描述&#xff1a; Lontium LT9211C是一个高性能转换器&#xff0c;可以在MIPI DSI/CSI-2/双端口LVDS和TTL之间相互转换&#xff0c;除了24位TTL到24位TTL&#xff0c;并且不推荐同步和DE的2端口10位LVDS和24位TTL之间的转换。LT9211C反序列化输入的MIPI/LVDS/TTL视…...

【Rust 基础篇】Rust 通道(Channel)

导言 在 Rust 中&#xff0c;通道&#xff08;Channel&#xff09;是一种用于在多个线程之间传递数据的并发原语。通道提供了一种安全且高效的方式&#xff0c;允许线程之间进行通信和同步。本篇博客将详细介绍 Rust 中通道的使用方法&#xff0c;包含代码示例和对定义的详细解…...

学习 C语言第二天 :C语言数据类型和变量(下)

目录&#xff1a; 1.变量的介绍以及存储 2.算术操作符、赋值操作符、单目操作符 3.scanf和printf的介绍 1.变量的介绍以及存储 1.1.变量的创建 了解了什么是类型了&#xff0c;类型是用来创建变量的。 变量是什么呢&#xff1f;在C语言当中不经常变的量称为常量&#xff0c;经常…...

【Kubernetes资源篇】ingress-nginx最佳实践详解

文章目录 一、Ingress Controller理论知识1、Ingress Controller、Ingress简介2、四层代理与七层代理的区别3、Ingress Controller中封装Nginx&#xff0c;为什么不直接用Nginx呢&#xff1f;4、Ingress Controller代理K8S内部Pod流程 二、实践&#xff1a;部署Ingress Control…...

Java基础阶段学习哪些知识内容?

Java是一种面向对象的编程语言&#xff0c;刚接触Java的人可能会感觉比较抽象&#xff0c;不要着急可以先从概念知识入手&#xff0c;先了解Java&#xff0c;再吃透Java&#xff0c;本节先来了解下Java的基础语法知识。 对象&#xff1a;对象是类的一个实例&#xff0c;有状态…...

【HISI IC萌新虚拟项目】ppu整体uvm验证环境搭建

关于整个虚拟项目,请参考: 【HISI IC萌新虚拟项目】Package Process Unit项目全流程目录_尼德兰的喵的博客-CSDN博客 前言 本篇文章完成ppu整体uvm环境搭建的指导,在进行整体环境搭建之前,请确认spt_utils、cpu_utils和ral_model均已经生成。此外,如果参考现在的工程目录…...

图像处理之hough圆形检测

hough检测原理 点击图像处理之Hough变换检测直线查看 下面直接描述检测圆形的方法 基于Hough变换的圆形检测方法 对于一个半径为 r r r&#xff0c;圆心为 &#xff08; a , b &#xff09; &#xff08;a,b&#xff09; &#xff08;a,b&#xff09;的圆&#xff0c;我们将…...

el-upload文件上传(只能上传一个文件且再次上传替换上一个文件) vue3+vite+ts

组件&#xff1a; <template><el-upload class"upload-demo" v-model:file-list"fileList" ref"uploadDemo" action"/public-api/api/file" multiple:on-preview"handlePreview" :on-remove"handleRemove&quo…...

随手笔记——根据点对来估计相机的运动综述

随手笔记——根据点对来估计相机的运动综述 说明计算相机运动 说明 简单介绍3种情况根据点对来估计相机运动所使用的方法 计算相机运动 有了匹配好的点对&#xff0c;接下来&#xff0c;要根据点对来估计相机的运动。这里由于相机的原理不同分为&#xff1a; 当相机为单目时…...

ip校园广播音柱特点

ip校园广播音柱特点IP校园广播音柱是一种基于IP网络技术的音频播放设备&#xff0c;广泛应用于校园、商业区、公共场所等地方。它可以通过网络将音频信号传输到不同的音柱设备&#xff0c;实现远程控制和集中管理。IP校园广播音柱具备以下特点和功能&#xff1a;1. 网络传输&am…...

用 Node.js 手写 WebSocket 协议

目录 引言 从 http 到 websocekt 的切换 Sec-WebSocket-Key 与 Sec-WebSocket-Accept 全新的二进制协议 自己实现一个 websocket 服务器 按照协议格式解析收到的Buffer 取出opcode 取出MASK与payload长度 根据mask key读取数据 根据类型处理数据 frame 帧 数据的发…...

Xilinx AXI VIP使用教程

AXI接口虽然经常使用&#xff0c;很多同学可能并不清楚Vivado里面也集成了AXI的Verification IP&#xff0c;可以当做AXI的master、pass through和slave&#xff0c;本次内容我们看下AXI VIP当作master时如何使用。 新建Vivado工程&#xff0c;并新建block design&#xff0c;命…...

mysql主主架构搭建,删库恢复

mysql主主架构搭建&#xff0c;删库恢复 搭建mysql主主架构环境信息安装msql服务mysql1mysql2设置mysql2同步mysql1设置mysql1同步mysql2授权测试用账户 安装配置keepalivedmysql1检查脚本mysql2检查脚本 备份策略mysqldump全量备份mysqldump增量备份数据库目录全量备份 删除my…...

pythonweek1

引言 做任何事情都要脚踏实地&#xff0c;虽然大一上已经学习了python的基础语法&#xff0c;大一下也学习了C加加中的类与对象&#xff0c;但是自我觉得基础还不太扎实&#xff0c;又害怕有什么遗漏&#xff0c;所以就花时间重新学习了python的基础&#xff0c;学习Python的基…...

进程虚拟地址空间区域划分

目录 图示 详解 代码段 备注&#xff1a;x86 32位linux环境下&#xff0c;进程虚拟地址空间区域划分 图示 详解 用户空间 用于存储用户进程代码和数据&#xff0c;只能由用户进程访问 内核空间 用于存储操作系统内核代码和数据&#xff0c;只能由操作系统内核访问 text t…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...