刚刚入门爬虫,今天先对于单个图集进行爬取,过几天再进行翻页爬取。

  使用requests库和BeautifulSoup库

  目标网站:妹子图

今天是对于单个图集的爬取,就选择一个进行爬取,我选择的链接为:http://www.mzitu.com/123114

首先网站的分析,该网站有一定的反爬虫策略,所以应对就是加入headers(目前是小白,目前不知道具体为毛这样做)

  1. Hostreferer = {
  2. 'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
  3. 'Referer':'http://www.mzitu.com'
  4. }
  5. Picreferer = {
  6. 'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
  7. 'Referer':'http://i.meizitu.net'
  8. }

前一个头作为请求网站,后一个头作为破解盗链使用

获得页面HTML代码

用requests库的get方法,加上Hostreferer

  1. def get_html(url):#获得页面html代码
  2. req = requests.get(url, headers=Hostreferer)
  3. html = req.text
  4. return html

获得图集名称以及图集最大页数

分析网页构成如图所示,图集名称包含在h2标签内,且该标签在整个HTML代码里有唯一的class="main-title",

而最大页数只是被span标签包含,无法通过属性来提取。所以提取图集名称采取标签名+属性名一起提取,而最大页数就采取将span标签全部找出,最大页数在span标签中第11位,

  1. def get_page_name(url):#获得图集最大页数和名称
  2. html = get_html(url)
  3. soup = BeautifulSoup(html, 'lxml')
  4. span = soup.findAll('span')
  5. title = soup.find('h2', class_="main-title")
  6. return span[10].text, title.text

获得图片url链接

  分析页面内容,含有图片链接的img标签中有一个alt属性的值是跟图集名称相同,可以用这个来直接找到这个标签,当然也可以先找到div标签中的class属性是main-inage,再找到img的src属性,这里我就采用第一种方法。

  1. def get_img_url(url, name):
  2. html = get_html(url)
  3. soup = BeautifulSoup(html, 'lxml')
  4. img_url = soup.find('img', alt= name)
  5. return img_url['src']

将图片存入本地

  得到图片url链接之后要讲图片存到本地,在请求图片url的时候要加入Picreferer,否则网站会认为你是一个爬虫,会返还给你一个盗链图

该方法传入的参数有3个,第一个是图片url,第二个当前图片的页数,用作创建文件,第三个是图集名称,在存储之前先创建了一个名称是图集名称的文件夹,这样就能将图片存入指定文件夹

  1. def save_img(img_url, count, name):
  2. req = requests.get(img_url, headers=Picreferer)
  3. with open(name+'/'+str(count)+'.jpg', 'wb') as f:
  4. f.write(req.content)

爬取一个图集完整代码

  1. import requests
  2. from bs4 import BeautifulSoup
  3. import os
  4.  
  5. Hostreferer = {
  6. 'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
  7. 'Referer':'http://www.mzitu.com'
  8. }
  9. Picreferer = {
  10. 'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
  11. 'Referer':'http://i.meizitu.net'
  12. }
  13.  
  14. def get_page_name(url):#获得图集最大页数和名称
  15. html = get_html(url)
  16. soup = BeautifulSoup(html, 'lxml')
  17. span = soup.findAll('span')
  18. title = soup.find('h2', class_="main-title")
  19. return span[10].text, title.text
  20.  
  21. def get_html(url):#获得页面html代码
  22. req = requests.get(url, headers=Hostreferer)
  23. html = req.text
  24. return html
  25.  
  26. def get_img_url(url, name):
  27. html = get_html(url)
  28. soup = BeautifulSoup(html, 'lxml')
  29. img_url = soup.find('img', alt= name)
  30. return img_url['src']
  31.  
  32. def save_img(img_url, count, name):
  33. req = requests.get(img_url, headers=Picreferer)
  34. with open(name+'/'+str(count)+'.jpg', 'wb') as f:
  35. f.write(req.content)
  36.  
  37. def main():
  38. old_url = "http://www.mzitu.com/123114"
  39. page, name = get_page_name(old_url)
  40. os.mkdir(name)
  41. for i in range(1, int(page)+1):
  42. url = old_url + "/" + str(i)
  43. img_url = get_img_url(url, name)
  44. #print(img_url)
  45. save_img(img_url, i, name)
  46. print('保存第' + str(i) + '张图片成功')
  47. main()

  在main方法中先请求到图集的名称和最大页数,并且使用名称创建一个文件夹来存储图片。再从1到最大页数做一个for循环,

然后图片的每一页是     图集首页 + / + 当前页数,得到含有图片内容的url链接,后面就可以将得到图片存入本地。

爬取结果

  文件夹名称即为图集名称,内部图片以页数作为文件名。

下面准备开始多个页面的爬取,先将前面爬取一个图集的方法进行封装

爬取一个图集

在进行爬取一个图集前先加入一个方法,在爬取图集名称的时候,由于名称的字符不限,所以可能出现含有文件夹中不能出现的一些字符,例如:/ \ : ? < > 等

所以需要将前面的代码进行修改,加入一个rename方法,将这些字符换成可行的字符。(在这里我就直接将这些字符去掉)

这里采用re库,将name中含有的非法字符换成空,可以看做直接去掉。

  1. import re
  2. def rename(name):
  3. rstr = r'[\/\\\:\*\?\<\>\|]'
  4. new_name = re.sub(rstr, "", name)
  5. return new_name
  6.  
  7. def save_one_atlas(old_url):
  8. page, name = get_page_name(old_url)
  9. new_name = rename(name)
  10. os.mkdir(new_name)
  11.  
  12. print("图集--" + name + "--开始保存")
  13. for i in range(1, int(page)+1):
  14. url = old_url + "/" + str(i)
  15. img_url = get_img_url(url, name)
  16. # print(img_url)
  17. save_img(img_url, i, name)
  18. print('正在保存第' + str(i) + '张图片')
  19. print("图集--" + name + "保存成功")

爬取一整页图集

  1. def get_atlas_list(url):
  2. req = requests.get(url, headers=Hostreferer)
  3. soup = BeautifulSoup(req.text, 'lxml')
  4. atlas = soup.find_all(attrs={'class':'lazy'})
  5. atlas_list = []
  6. for atla in atlas:
  7. atlas_list.append(atla.parent['href'])
  8. return atlas_list

分析一个页面中的url链接,发现如果找 target="_blank" 这一属性,则会产生很多多余的链接,所以我直接从字标签入手找到属性 class="lazy"的img标签,然后再在寻找到img标签的父标签中的href

  1. def save_one_page(start_url):
  2. atlas_url = get_atlas_list(start_url)
  3. for url in atlas_url:
  4. save_one_atlas(url)

将爬取一整夜图集进行封装,方便后续的翻页爬取

翻页爬取

分析页面url,发现每一页均是初始网址+page/+页数/

第一页是初始网址,但是页数为1的链接也是直接进入第一页,所以所有页的url就可以用以上通式改变页数进行遍历。

  1. start_url = "http://www.mzitu.com/"
  2. for count in range(1, 3):
  3. url = start_url + "page/" + str(count) +"/"
  4. save_one_page(url)

这里作为测试,所以只爬取前两页图集。改变range内的参数,即可改变爬取页数。

完整代码

  1. import requests
  2. from bs4 import BeautifulSoup
  3. import os
  4. import re
  5.  
  6. Hostreferer = {
  7. 'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
  8. 'Referer':'http://www.mzitu.com'
  9. }
  10. Picreferer = {
  11. 'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
  12. 'Referer':'http://i.meizitu.net'
  13. }
  14.  
  15. def get_page_name(url):#获得图集最大页数和名称
  16. html = get_html(url)
  17. soup = BeautifulSoup(html, 'lxml')
  18. span = soup.findAll('span')
  19. title = soup.find('h2', class_="main-title")
  20. return span[10].text, title.text
  21.  
  22. def get_html(url):#获得页面html代码
  23. req = requests.get(url, headers=Hostreferer)
  24. html = req.text
  25. return html
  26.  
  27. def get_img_url(url, name):
  28. html = get_html(url)
  29. soup = BeautifulSoup(html, 'lxml')
  30. img_url = soup.find('img', alt= name)
  31. return img_url['src']
  32.  
  33. def save_img(img_url, count, name):
  34. req = requests.get(img_url, headers=Picreferer)
  35. new_name = rename(name)
  36. with open(new_name+'/'+str(count)+'.jpg', 'wb') as f:
  37. f.write(req.content)
  38.  
  39. def rename(name):
  40. rstr = r'[\/\\\:\*\?\<\>\|]'
  41. new_name = re.sub(rstr, "", name)
  42. return new_name
  43.  
  44. def save_one_atlas(old_url):
  45. page, name = get_page_name(old_url)
  46. new_name = rename(name)
  47. os.mkdir(new_name)
  48.  
  49. print("图集--" + name + "--开始保存")
  50. for i in range(1, int(page)+1):
  51. url = old_url + "/" + str(i)
  52. img_url = get_img_url(url, name)
  53. # print(img_url)
  54. save_img(img_url, i, name)
  55. print('正在保存第' + str(i) + '张图片')
  56. print("图集--" + name + "保存成功")
  57.  
  58. def get_atlas_list(url):
  59. req = requests.get(url, headers=Hostreferer)
  60. soup = BeautifulSoup(req.text, 'lxml')
  61. atlas = soup.find_all(attrs={'class':'lazy'})
  62. atlas_list = []
  63. for atla in atlas:
  64. atlas_list.append(atla.parent['href'])
  65. return atlas_list
  66.  
  67. def save_one_page(start_url):
  68. atlas_url = get_atlas_list(start_url)
  69. for url in atlas_url:
  70. save_one_atlas(url)
  71.  
  72. if __name__ == '__main__':
  73. start_url = "http://www.mzitu.com/"
  74. for count in range(1, 3):
  75. url = start_url + "page/" + str(count) +"/"
  76. save_one_page(url)
  77. print("爬取完成")

这个程序能够爬取图片,但是效率太低,正在学习多进程,希望之后可以提高该程序的爬取效率。

我爬了3个多G的图片花了我接近4个小时,足以证明效率是真的低。

并且在爬取过程中出现一个问题,提示 你的主机中的软件中止了一个已建立的连接 ,这个问题还未找到解决方法,也未找明产生的具体原因。

这是我写的第一篇较长的博客,还有很多未完善的地方,希望大家见谅。

爬取妹子图(requests + BeautifulSoup)的更多相关文章

  1. Python协程爬取妹子图(内有福利,你懂得~)

    项目说明: 1.项目介绍   本项目使用Python提供的协程+scrapy中的选择器的使用(相当好用)实现爬取妹子图的(福利图)图片,这个学会了,某榴什么的.pow(2, 10)是吧! 2.用到的知 ...

  2. Python3爬虫系列:理论+实验+爬取妹子图实战

    Github: https://github.com/wangy8961/python3-concurrency-pics-02 ,欢迎star 爬虫系列: (1) 理论 Python3爬虫系列01 ...

  3. 使用requests+BeaBeautiful Soup爬取妹子图图片

    1. Requests:让 HTTP 服务人类 Requests 继承了urllib2的所有特性.Requests支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动确定 ...

  4. python爬取妹子图全站全部图片-可自行添加-线程-进程爬取,图片去重

    from bs4 import BeautifulSoupimport sys,os,requests,pymongo,timefrom lxml import etreedef get_fenlei ...

  5. 猫眼电影爬取(二):requests+beautifulsoup,并将数据存储到mysql数据库

    上一篇通过requests+正则爬取了猫眼电影榜单,这次通过requests+beautifulsoup再爬取一次(其实这个网站更适合使用beautifulsoup库爬取) 1.先分析网页源码 可以看 ...

  6. Python网络爬虫 | Scrapy爬取妹子图网站全站照片

    根据现有的知识,写了一个下载妹子图(meizitu.com)Scrapy脚本,把全站两万多张照片下载到了本地. 网站的分析 网页的网址分析 打开网站,发现网页的网址都是以 http://www.mei ...

  7. Python 2.7和3.6爬取妹子图网站单页测试图片

    1.url= http://www.mzitu.com/74100/x,2为1到23的值 2.用到模块 os 创建文件目录; re模块正则匹配目录名 图片下载地址; time模块 限制下载时间;req ...

  8. Python 2.7_爬取妹子图网站单页测试图片_20170114

    1.url= http://www.mzitu.com/74100/x,2为1到23的值 2.用到模块 os 创建文件目录; re模块正则匹配目录名 图片下载地址; time模块 限制下载时间;req ...

  9. Python 爬取妹子图(技术是无罪的)

    ... import requests from bs4 import BeautifulSoup import os import sys class mzitu(): def html(self, ...

随机推荐

  1. Several ports (8005, 8080, 8009) required by Tomcat v8.5 Server at localhost are already in use. The server may already be running in another process, or a system process may be using the port. To sta

    eclipse出现:Several ports (8005, 8080, 8009) required by Tomcat v8.5 Server at localhost are already i ...

  2. sql字段为datetime,插入''的时候默认为1900年

    Microsoft SQL Server Database Engine 用两个 4 字节的整数内部存储 datetime 数据类型的值. 第一个 4 字节存储“基础日期”(即 1900 年 1 月  ...

  3. data-ng-disabled指令

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  4. css3中有关transform的问题

    Transform属性应用于元素的2D或3D转换.这个属性允许你将元素旋转,缩放,移动,倾斜等.

  5. vue 修改框架less变量

    以vant框架为例,vue项目以less作为css处理器: less/var-reset.less @import '~vant/lib/index.less'; // Color variables ...

  6. Python 学习笔记(七)Python字符串(四)

    输入输出 输入函数 raw_input (Python3:input) >>> raw_input("请输入一个字母") #获取输入内容的一个函数 请输入一个字母 ...

  7. 虚拟内存设置(解决linux内存不够情况)

    一.      虚拟内存介绍 背景介绍 Memory指机器物理内存,读写速度低于CPU一个量级,但是高于磁盘不止一个量级.所以,程序和数据如果在内存的话,会有非常快的读写速度.但是,内存的造价是要高于 ...

  8. Co. - Microsoft - Windows - Tomcat、JDK、MySQL通过 Inno 集成为exe部署包

    需求 客户设备为Windows系统,需要部署公司产品,因此将Tomcat.JDK.MySQL.Java.war 打包整合成exe文件,Windows下一键部署安装. 最佳实践 1.下载免安装的mysq ...

  9. 针对 npm ERR! cb() never called! 问题

    在开发项目安装依赖时(npm install) 往往会报  npm ERR! cb()never called!的错误 如图: 解决方法: 一.首先要以管理员模式打开cmd清除你的npm缓存 : np ...

  10. thinkphp3.2.3实现多条件查询实例.

    $data = M("datainfo"); $projectsname = I('get.projectsname');//前台提交的模糊查询字段 // 查询条件 $where ...