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

Python实现一个简单的图片爬虫

前言

提起爬虫,很多人都会感觉很神秘,包括以前的我也是一样的,只要是和爬虫的相关的知识我都感觉很高端,后来渐渐的接触的多了,也就慢慢地明白的了究竟什么是爬虫,说说我理解的吧,爬虫本身是一项技术,很有用的一项技术,但是如果被毫无节制的使用,不仅会侵犯他人的知识产权,同时还会浪费过多的服务器资源。

其实爬虫访问的绝大多数都是正常的网站,只不过它不需要人们正常的打开浏览器输入网址,就可以访问到浏览器中的内容,比如我们可以直接获取到某个网站首页的新闻,或者得到某个数据网站的表格数据,通俗的来说就是通过编写程序来模拟人访问网站的行为,来获取网站页面中的数据。

接下来我来写个小例子来实现一个图片爬虫的功能,本文涉及到的代码只是想说明爬虫的作用,让大家了解一下爬虫并不是那么神秘,所写代码只做学习使用,切记不可用来做获取非法的内容,其实接下来的代码很简单,只能实现很有限的功能,想要做成有实际作用的爬虫真得好好下一番功夫才行。

代码实现

首先我们得引入爬虫实现中经常要使用的库:

import urllib.request, re, os

其中urllib.request是用来发起去HTTP请求的,re是使用正则表达是查找的,os是用来做一些系统级别的操作的。

接下来定义一下变量:

# save file path
target_path = "images_crawler_results"
# target url that needs to crawler
target_url = "https://www.csdn.net/"
# request data headers
req_headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36' }

前两个变量很容易理解,这里不再赘述,既然是在CSDN上发表的,那就干脆抓一下CSDN首页(https://www.csdn.net/)的图片好了,详细说一下最后一个字典类型的变量,实际上就是为了骗过网站服务器,让它感觉是真正的一个人在访问网站,而不是一段程序,这里不得不提一下HTTP请求的一些参数,HTTP 的请求头是在你每次向网络服务器发送请求时,传递的一组属性和配置信息,HTTP 定义了十几种古怪的请求头类型,不过大多数都不常用,只有几种是很常用的,比如:

属性示例
Hosthttps://www.csdn.net/
Connectionkeep-alive
User-AgentMozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36
Accept-Languageen-US,en;q=0.8

这里最重要的参数就是User-Agent了,如果使用默认参数,那么这一项的值默认是Python-urllib/3.4,是不是很尴尬,这样一眼不就看出来是程序自动处理的嘛,所以我们要伪装一下,使用变量req_headers中的值

接下来定义一个函数,用来获取保存下载图片需要保存的路径,根据图片的名字命名图片,并且同意保存到目录images_crawler_results中:

def get_file_local_path(file_path):
    file_name = os.path.split(file_path)[1]
    return os.path.join(target_path, file_name)

接着我们再定义一个函数start_crawler来启动我们的爬虫,首先检查一下目录images_crawler_results是否存在,如果不存在就创建一个:

if not os.path.isdir(target_path):
    os.mkdir(target_path)

然后发送HTTP请求获得数据,数据以二进制形式保存在变量data中:

req = urllib.request.Request(url = target_url, headers = req_headers)
res = urllib.request.urlopen(req)
data = res.read()

最后,在变量data中利用正则表达式查找出所有图片的链接,然后下载保存在本地:

for link, t in set(re.findall(r'(images.csdn.net[\S]*?(jpg|png|gif))', data.decode('utf8'))):
   reallink = 'https://' + urllib.request.quote(link)
   print(reallink)
   try:
       urllib.request.urlretrieve(reallink, get_file_local_path(link))
   except:
       print('crawler failed')

这段代码中比较重要是data.decode('utf8')这一句,就是把HTTTP请求的返回的二进制数据按照utf8编码解析出来,这样通过正则表达式查找出来的图片路径就是正常的,但是有些是中文,如果不做处理就会下载失败,所以后面又加上了urllib.request.quote(link)就是为了对链接进行URL编码,最后通过函数urllib.request.urlretrieve就可以保存在本地了啊,是不是很简单呢?

总结

  1. 网络爬虫本身是一门很有用的技术,但是也是一把双刃剑,用错了害人害己,当然了如果只是为了减轻工作量,避免一些重复性操作,在不影响他人的情况下,我感觉偶尔用用还是不错的。
  2. 网络爬虫博大精深,需要仔细钻研才能解决实际操作中的文问题,比如这个小例子中,一开始就无法现在中文的图片,后来通过转码和URL编码才解决。

源代码

完整代码传送门,有什么问题,欢迎大家反馈!

相关文章:

  • 验证mysql联合索引最左原则
  • Mysql查询时case when语句的使用
  • Vim中简单格式化代码
  • Vim、Xshell、远程终端莫名卡死的原因
  • 关于游戏中仓库类的设计
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • 神秘莫测的时间复杂度
  • 排序算法系列之(三)——略显神秘的快速排序
  • .bat批处理(六):替换字符串中匹配的子串
  • 操作指向类成员的指针需要了解的两个操作符-*和.*
  • VS2015调试dump文件时提示未找到xxx.exe或xxx.dll
  • 结构体sockaddr、sockaddr_in、sockaddr_in6之间的区别和联系
  • 简述TCP三次握手和四次挥手流程
  • 智能指针(零):分类及简单特性
  • 智能指针(一):auto_ptr浅析
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • Angular 响应式表单 基础例子
  • angular2 简述
  • Apache Spark Streaming 使用实例
  • CSS中外联样式表代表的含义
  • Redis的resp协议
  • SQL 难点解决:记录的引用
  • Vue.js源码(2):初探List Rendering
  • 第2章 网络文档
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 前端js -- this指向总结。
  • 设计模式(12)迭代器模式(讲解+应用)
  • 通过npm或yarn自动生成vue组件
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • MPAndroidChart 教程:Y轴 YAxis
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • ​ArcGIS Pro 如何批量删除字段
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • #Linux(帮助手册)
  • (09)Hive——CTE 公共表达式
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (四)Controller接口控制器详解(三)
  • (转) 深度模型优化性能 调参
  • . Flume面试题
  • .net Application的目录
  • .net core 控制台应用程序读取配置文件app.config
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .net 怎么循环得到数组里的值_关于js数组
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • .NET企业级应用架构设计系列之结尾篇
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • .Net转前端开发-启航篇,如何定制博客园主题
  • /bin/bash^M: bad interpreter: No such file ordirectory
  • @Autowired @Resource @Qualifier的区别
  • @synthesize和@dynamic分别有什么作用?