有些数据是没有专门的数据集的,为了找到神经网络训练的数据,自然而然的想到了用爬虫的方法开始采集数据。一开始采用了网上的一个动态爬虫的代码,发现爬取的图片大多是重复的,有效图片很少。

动态爬虫:

  1. from lxml import etree
  2. import requests
  3. import re
  4. import urllib
  5. import json
  6. import time
  7. import os
  8.  
  9. local_path = '/home/path/'
  10. if not os.path.exists(local_path):
  11. os.makedirs(local_path)
  12. keyword = input('请输入想要搜索图片的关键字:')
  13. first_url = 'http://image.baidu.com/search/flip?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1530850407660_R&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&ctd=1530850407660%5E00_1651X792&word={}'.format(keyword)
  14. want_download = input('请输入想要下载图片的张数:')
  15.  
  16. global page_num
  17. page_num = 1
  18. global download_num
  19. download_num = 0
  20.  
  21. #这个函数用来获取图片格式
  22. def get_format(pic_url):
  23. #url的末尾存着图片的格式,用split提取
  24. #有些url末尾并不是常见图片格式,此时用jpg补全
  25. t = pic_url.split('.')
  26. if t[-1].lower() != 'bmp' and t[-1].lower() != 'gif' and t[-1].lower() != 'jpg' and t[-1].lower() != 'png':
  27. pic_format = 'jpg'
  28. else:
  29. pic_format = t[-1]
  30. return pic_format
  31.  
  32. #这个函数用来获取下一页的url
  33. def get_next_page(page_url):
  34. global page_num
  35. html = requests.get(page_url).text
  36. with open('html_info.txt', 'w', encoding='utf-8') as h:
  37. h.write(html)
  38. selector = etree.HTML(html)
  39. try:
  40. msg = selector.xpath('//a[@class="n"]/@href')
  41. print(msg[0])
  42. next_page = 'http://image.baidu.com/' + msg[0]
  43. print('现在是第%d页' % (page_num + 1))
  44. except Exception as e:
  45. print('已经没有下一页了')
  46. print(e)
  47. next_page = None
  48. page_num = page_num + 1
  49. return next_page
  50.  
  51. #这个函数用来下载并保存图片
  52. def download_img(pic_urls):
  53. count = 1
  54. global download_num
  55. for i in pic_urls:
  56. time.sleep(1)
  57. try:
  58. pic_format = get_format(i)
  59. pic = requests.get(i, timeout=15)
  60. #按照格式和名称保存图片
  61. with open(local_path + 'page%d_%d.%s' % (page_num, count, pic_format), 'wb') as f:
  62. f.write(pic.content)
  63. #print('成功下载第%s张图片: %s' % (str(count), str(pic.url)))
  64. count = count + 1
  65. download_num = download_num + 1
  66. except Exception as e:
  67. #print('下载第%s张图片时失败: %s' % (str(count), str(pic.url)))
  68. print(e)
  69. count = count + 1
  70. continue
  71. finally:
  72. if int(want_download) == download_num:
  73. return 0
  74.  
  75. #这个函数用来提取url中图片的url
  76. def get_pic_urls(web_url):
  77. html = requests.get(web_url).text
  78. #通过正则表达式寻找图片的地址,
  79. pic_urls = re.findall('"objURL":"(.*?)",', html, re.S)
  80. #返回图片地址,是一个list
  81. return pic_urls
  82.  
  83. if __name__ == "__main__":
  84. while True:
  85. pic_urls = get_pic_urls(first_url)
  86. t = download_img(pic_urls)
  87. if t==0:
  88. break
  89. next_url = get_next_page(first_url)
  90. if next_url == None:
  91. print('已经没有更多图片')
  92. break
  93. pic_urls = get_pic_urls(next_url)
  94. t = download_img(pic_urls)
  95. if t== 0:
  96. break
  97. first_url = next_url
  98. #print('已经成功下载%d张图片' %download_num)

为了筛选出重复的图片又采用了哈希算法进行去重

  1. # -*- coding: utf-8 -*-
  2.  
  3. import sys
  4. reload(sys)
  5. sys.setdefaultencoding('utf8')
  6.  
  7. """
  8. 用dhash判断是否相同照片
  9. 基于渐变比较的hash
  10. hash可以省略(本文省略)
  11. By Guanpx
  12. """
  13. import os
  14. from PIL import Image
  15. from os import listdir
  16.  
  17. def picPostfix(): # 相册后缀的集合
  18. postFix = set()
  19. postFix.update(['bmp', 'jpg', 'png', 'tiff', 'gif', 'pcx', 'tga', 'exif',
  20. 'fpx', 'svg', 'psd', 'cdr', 'pcd', 'dxf', 'ufo', 'eps', 'JPG', 'raw', 'jpeg'])
  21. return postFix
  22.  
  23. def getDiff(width, high, image): # 将要裁剪成w*h的image照片
  24. diff = []
  25. im = image.resize((width, high))
  26. imgray = im.convert('L') # 转换为灰度图片 便于处理
  27. pixels = list(imgray.getdata()) # 得到像素数据 灰度0-255
  28.  
  29. for row in range(high): # 逐一与它左边的像素点进行比较
  30. rowStart = row * width # 起始位置行号
  31. for index in range(width - 1):
  32. leftIndex = rowStart + index
  33. rightIndex = leftIndex + 1 # 左右位置号
  34. diff.append(pixels[leftIndex] > pixels[rightIndex])
  35.  
  36. return diff # *得到差异值序列 这里可以转换为hash码*
  37.  
  38. def getHamming(diff=[], diff2=[]): # 暴力计算两点间汉明距离
  39. hamming_distance = 0
  40. for i in range(len(diff)):
  41. if diff[i] != diff2[i]:
  42. hamming_distance += 1
  43.  
  44. return hamming_distance
  45.  
  46. if __name__ == '__main__':
  47.  
  48. width = 32
  49. high = 32 # 压缩后的大小
  50. dirName = "/home/yourpath" # 相册路径
  51. allDiff = []
  52. postFix = picPostfix() # 图片后缀的集合
  53.  
  54. dirList = os.listdir(dirName)
  55. cnt = 0
  56. for i in dirList:
  57. cnt += 1
  58. # print('文件处理的数量是', cnt) # 可以不打印 表示处理的文件计数
  59. if str(i).split('.')[-1] in postFix: # 判断后缀是不是照片格式
  60. try:
  61. im = Image.open(r'%s/%s' % (dirName, unicode(str(i), "utf-8")))
  62. except OSError as err:
  63. os.remove(r'%s/%s' % (dirName, unicode(str(i), "utf-8")))
  64. print('OS error : {}'.format(err))
  65. # continue
  66.  
  67. except IndexError as err:
  68. os.remove(r'%s/%s' % (dirName, unicode(str(i), "utf-8")))
  69. print('OS error : {}'.format(err))
  70. print('Index Error: {}'.format(err))
  71. # continue
  72.  
  73. except IOError as err:
  74. os.remove(r'%s/%s' % (dirName, unicode(str(i), "utf-8"))) # 删除图片
  75. # print('OS error : {}'.format(err))
  76. print('IOError : {}'.format(err))
  77. # continue
  78.  
  79. # except:
  80. # print ('Other error')
  81. else:
  82. diff = getDiff(width, high, im)
  83. allDiff.append((str(i), diff))
  84.  
  85. for i in range(len(allDiff)):
  86. for j in range(i + 1, len(allDiff)):
  87. if i != j:
  88. ans = getHamming(allDiff[i][1], allDiff[j][1])
  89. if ans <= 5: # 判别的汉明距离,自己根据实际情况设置
  90. print(allDiff[i][0], "and", allDiff[j][0], "maybe same photo...")
  91. result = dirName + "/" + allDiff[j][0]
  92. if os.path.exists(result):
  93. os.remove(result)

用哈希算法筛选后又发现筛除的太多了,阈值不好控制。又尝试采用了静态爬虫的方法,发现结果还不错,重复的也不多,也就省了筛除的步骤。

静态爬虫:

  1. # -*- coding: utf-8 -*-
  2. import sys
  3. reload(sys)
  4. sys.setdefaultencoding('utf8')
  5. import time
  6. # 导入需要的库
  7. import requests
  8. # import os
  9. import json
  10. import time
  11.  
  12. # 爬取百度图片,解析页面的函数
  13. def getManyPages(keyword, pages):
  14. '''
  15. 参数keyword:要下载的影像关键词
  16. 参数pages:需要下载的页面数
  17. '''
  18. params = []
  19.  
  20. for i in range(30, 30 * pages + 30, 30):
  21. params.append({
  22. 'tn': 'resultjson_com',
  23. 'ipn': 'rj',
  24. 'ct': 201326592,
  25. 'is': '',
  26. 'fp': 'result',
  27. 'queryWord': keyword,
  28. 'cl': 2,
  29. 'lm': -1,
  30. 'ie': 'utf-8',
  31. 'oe': 'utf-8',
  32. 'adpicid': '',
  33. 'st': -1,
  34. 'z': '',
  35. 'ic': 0,
  36. 'word': keyword,
  37. 's': '',
  38. 'se': '',
  39. 'tab': '',
  40. 'width': '',
  41. 'height': '',
  42. 'face': 0,
  43. 'istype': 2,
  44. 'qc': '',
  45. 'nc': 1,
  46. 'fr': '',
  47. 'pn': i,
  48. 'rn': 30,
  49. 'gsm': '1e',
  50. '': ''
  51. })
  52. url = 'https://image.baidu.com/search/acjson'
  53. urls = []
  54. for i in params:
  55. try:
  56. urls.append(requests.get(url, params=i).json().get('data'))
  57. # except json.decoder.JSONDecodeError:
  58. # print("解析出错")
  59.  
  60. except OSError as err:
  61. print('OS error : {}'.format(err))
  62.  
  63. except IndexError as err:
  64. print('Index Error: {}'.format(err))
  65.  
  66. except IOError as err:
  67. print('IOError : {}'.format(err))
  68. except:
  69. print('Other error')
  70. return urls
  71.  
  72. # 下载图片并保存
  73. def getImg(dataList, localPath):
  74. '''
  75. 参数datallist:下载图片的地址集
  76. 参数localPath:保存下载图片的路径
  77. '''
  78. if not os.path.exists(localPath): # 判断是否存在保存路径,如果不存在就创建
  79. os.mkdir(localPath)
  80. x = 0
  81. for list in dataList:
  82. for i in list:
  83. if i.get('thumbURL') != None:
  84. # print('正在下载:%s' % i.get('thumbURL'))
  85. ir = requests.get(i.get('thumbURL'))
  86. open(localPath + '/' + '%d.jpg' % x, 'wb').write(ir.content) # 这里是新加的斜杠
  87. x += 1
  88. else:
  89. print('图片链接不存在')
  90.  
  91. # 根据关键词来下载图片
  92. if __name__ == '__main__':
  93. import os
  94. father_path = "/home/yourpath/"
  95. t0 = time.time()
  96. for init in os.listdir(father_path):
  97. print('init is{}'.format(str(init)))
  98. for name in os.listdir(init):
  99. print('name is{}'.format(str(name)))
  100. t1 = time.time()
  101. if not os.listdir(os.path.join(father_path, init, name)):
  102. dataList = getManyPages(name, 30)
  103. getImg(dataList, os.path.join(father_path, init, name))
  104. t2 = time.time()
  105. print('cost time is', t2 - t1)
  106. t3 = time.time()
  107. print('total time is', t3 - t0)
  108. # t1 = time.time()
  109. # dataList = getManyPages('keyword', page
  110. _number) # 参数1:关键字,参数2:要下载的页数
  111. # getImg(dataList, './file_path/') # 参数2:指定保存的路径
  112. # t2 = time.time()
  113. # print('cost time is', t2 - t1)
  114. #
  115. # parent_name = "/home/path" # 相册路径
  116. # dirList = os.listdir(parent_name) # 所有文件夹的列表
  117. # for one_file in dirList: # 其中的一个文件夹
  118. # # son_list = os.listdir(one_file)
  119. # son_list = os.path.join(parent_name, one_file)
  120. # son_file = os.listdir(son_list)
  121. # t1 = time.time()

Python爬虫小结的更多相关文章

  1. python爬虫小结1

    先看正则化,正则化就是描述命令和字符切分.查找.筛选等功能的方便方式. http://www.cnblogs.com/fnng/archive/2013/05/20/3089816.html 一个游戏 ...

  2. 【Python爬虫】爬虫利器 requests 库小结

    requests库 Requests 是一个 Python 的 HTTP 客户端库. 支持许多 HTTP 特性,可以非常方便地进行网页请求.网页分析和处理网页资源,拥有许多强大的功能. 本文主要介绍 ...

  3. Python爬虫 股票数据爬取

    前一篇提到了与股票数据相关的可能几种数据情况,本篇接着上篇,介绍一下多个网页的数据爬取.目标抓取平安银行(000001)从1989年~2017年的全部财务数据. 数据源分析 地址分析 http://m ...

  4. Python字典小结

      字典(dict)结构是Python中常用的数据结构,笔者结合自己的实际使用经验,对字典方面的相关知识做个小结,希望能对读者一些启发~ 创建字典   常见的字典创建方法就是先建立一个空字典,然后逐一 ...

  5. 0.Python 爬虫之Scrapy入门实践指南(Scrapy基础知识)

    目录 0.0.Scrapy基础 0.1.Scrapy 框架图 0.2.Scrapy主要包括了以下组件: 0.3.Scrapy简单示例如下: 0.4.Scrapy运行流程如下: 0.5.还有什么? 0. ...

  6. 路飞学城Python爬虫课第一章笔记

    前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 之前看阮一峰的博客文章,介绍到路飞学城爬虫课程限免,看了眼内容还不错,就兴冲冲报了名,99块钱满足以下条件会返还并送书送视频. 缴 ...

  7. Python爬虫视频教程

    ├─第1章_[第0周]网络爬虫之前奏 │ ├─第1节_"网络爬虫"课程内容导学 │ │ 第1部分_全课程内容导学.mp4 │ │ 第2部分_全课程内容导学(WS00单元)学习资料. ...

  8. Python爬虫之小试牛刀——使用Python抓取百度街景图像

    之前用.Net做过一些自动化爬虫程序,听大牛们说使用python来写爬虫更便捷,按捺不住抽空试了一把,使用Python抓取百度街景影像. 这两天,武汉迎来了一个德国总理默克尔这位大人物,又刷了一把武汉 ...

  9. Python 爬虫入门实战

    1. 前言 首先自我介绍一下,我是一个做 Java 的开发人员,从今年下半年开始,一直在各大技术博客网站发表自己的一些技术文章,差不多有几个月了,之前在 cnblog 博客园加了网站统计代码,看到每天 ...

随机推荐

  1. CentOS7.2 部署Ceph分布式存储

    1.1 环境准备 主机名 IP地址 ceph-admin 192.168.16.220 ceph-node1,ceph-mon 192.168.16.221 ceph-node2,ceph-mon 1 ...

  2. virtualenv虚拟环境使用及介绍

    一.为什么使用virtualenv虚拟环境 每个虚拟环境下的依赖相互独立,不同的项目可以单独使用一套python环境,减少各依赖包的影响 更容易部署 容器化 二.virtualenv创建虚拟环境 三. ...

  3. Windows和Linux下与VMware虚拟机通过内网IP通讯

    首先分两种情况:一种是你的电脑已经在一个内网的环境下且有额外的内网IP地址,和另一种只是想给自己电脑上的虚拟机分配个内网IP来通讯. ①有可用的内网IP 找到一个空闲的IP地址(这里以192.168. ...

  4. 入门Grunt前端构建工具

    1. 全局安装 grunt:(倘若之前电脑安装过,则跳过此步骤) $ cnpm install -g grunt-cli 2. 作为项目的开发依赖(devDependencies)安装: (此步骤会自 ...

  5. C# 删除指定文件

    using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;us ...

  6. EF 使用lambda表达式 更新一对多数据时报错

    1.需求  更新一对多表中的附表数据,表结构如下: 2.思路 个人觉得一个个去对比关联的附表数据是删除还是添加比较麻烦,就直接清空主表关联的附表,然后重新建立关联关系. 3.弊端 如果附表(前提是附表 ...

  7. MySQL快速回顾:更新和删除操作

    前提要述:参考书籍<MySQL必知必会> 6.1 更新数据 为了更新(修改)表中的数据,可使用UPDATE语句.可采用两种方式使用UPDATE: 更新表中特定的行: 更新表中所有的行. U ...

  8. 3maven常用命令和配置依赖

    依赖: 例:spring-context.jar 依赖 spring-aop.jar... A中的某些类 需要使用B中的某些类,则称为A依赖于B 在maven项目中,如果要使用 一个当时存在的Jar或 ...

  9. springboot +fastdfs 上传文件到到云服务器

    fastdfs在云服务器的搭建和配置:https://blog.csdn.net/qq_41592652/article/details/104006289 springboot结构如下: appli ...

  10. CentOS6.8 LAMP

    第一次配置LAMP运行环境,上网查询了很多资料,一边试命令一边学习.服务器重置了很多次. 虽然有OneinStack这个方便的网站一键命令部署,但知道这个网站却是我自己踩坑之后的事情了,故此记录. 1 ...