原博主地址:http://cuiqingcai.com/1001.html

原博是python2.7写的,并且随着淘宝代码的改版,原博爬虫已经不可用。

参考 http://minstrel.top/TaoBaoMM 这位博主跟我一样最近正在学习爬虫。

1 定个小目标

lcw先生听说我即将爬取美女的照片,两眼都亮了。没错,我要给他福利了(其实女生也很喜欢美女)。

所以,定个最小的目标:

1.在F盘建立美女文件夹

2.文件夹下按照淘女郎美人库默认美人排序,抓取31个美女的信息(因为一页默认是30个人,不至于太少,也能太多要不然抓取时间太多,lcw的破电脑也装不下)

3.每个以美人名字命名的文件夹下,取10张照片(内容小,别介)

2 抓取过程

进入淘女郎首页之后,点击找模特,进入我们需要爬取的页面。可以看到页面上是默认tag在美人库上。也即是有30位默认的美人出现在页面。每一位有相应的照片以及个人信息。30位美人下方,是页码和总美人数的信息。因为我也是web出身。像这种信息和数量都有变化的信息展示,肯定不是静态页面。一般都是通过js动态加载而来。通过开发者工具(google浏览器,F12, Json handle插件 感谢小伙伴告诉我这个插件),动态监控network.在查找加载信息的http时,我犯了个错误,一直以为返回的信息应该是json信息。这是我们post返回结果最常见的格式,但事实是返回的xhr信息。这就是抓包工具用得少的下场,哭。

明确了type是xhr后,很快找到了这个:

  https://mm.taobao.com/tstar/search/tstar_model.do?_input_charset=utf-8

在headers里面 fromdata中查看source可以看到参数列表:

q=&viewFlag=A&sortType=default&searchStyle=&searchRegion=city%3A&searchFansNum=¤tPage=2&pageSize=100

我们只需要currentPage这个参数。

   
https://mm.taobao.com/tstar/search/tstar_model.do?_input_charset=utf-8&currentPage=2可以立刻看到下一页的信息。


输入这个网址,借助json handle插件得到:

可以看到页面上清楚的显示了当前页面上30位佳丽的信息,以及当前页面,总共美女数目。其实这些信息也可以通过正则匹配来得到,不过相对于直接使用js获取,肯定后者更快捷。2 目标 1.找到模特总页数 2.找到所得页的模特的json格式的信息,这一步主要为了获取每个模特的id。只有知道id才能进入到她的主页。这里有一个十分重要的信息,是之前我忽略了的。就是动态页面。爬虫通过url可以得到一个页面,也无法得到加载该页面时通过参数动态加载的内容。所以,这里想要通过url直接得到模特的信息内容是不可能的。这是静态页面与动态页面的区别。 3.找到相册总页数 4.找到所得相册页的json格式的信息。与第二步相似。得到每个相册的id. 5.通过相册id得到每个相册的url。通过该url爬取该相册下的内容。

 (身为一个大写的直男,lcw同学在看到我的目标之后,提出了更进一步的要求:要筛选出理想身高理想颜值的mm。好,   后期为你实现。)

3 按照目标步骤写程序 3.1 根据https://mm.taobao.com/tstar/search/tstar_model.do?_input_charset=utf-8&currentPage=1可以得到上述图片中展示的信息。程序如下:
#!usr/bin/env/python
#encoding:UTF-8import urllib
import requests
import json
import os
import re
import timecurrentPage = 1headers = {'User-Agent': r'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT) 'r'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3','Connection': 'keep-alive'}
url = 'https://mm.taobao.com/tstar/search/tstar_model.do?_input_charset=utf-8'
try:data = urllib.parse.urlencode({"currentPage":currentPage}).encode('utf-8')request = urllib.request.Request(url,data = data, headers = headers)res = urllib.request.urlopen(request).read().decode('gbk')print(res)
except urllib.error.URLError as e:if hasattr(e, "reason"):print("连接失败,错误原因:",e.reason)
注意,这里的res是使用gbk。这个也是通过network中查看response得到的。

3.2 点击一位模特(以朱琳为例)的主页面,得到地址https://mm.taobao.com/self/model_album.htm?
spm=719.7800510.a312r.17.xcy6bS&user_id=176817195。spm不知道是什么暂时不管。user_id已经通过上面的json
得到了。那么怎么得到动态加载得到的相册信息呢。F12,刷新查看,得到返回值为xhr的一个请求地址:https://mm.taobao.com/self/album/open_album_list.htm?_charset=utf-8&user_id%20=176817195。
在地址栏输入上面的地址得到图片:

以上信息虽然不是json格式的信息,但是我们欣喜的发现,所需要的信息全部在这里。用爬虫获取上述url的html内容

相册ID和相册总页数都得到了。其实跟json差不多。
多说一句。本来我查看原始页面,不是这个中间请求页面时,想要根据下面这个获得总的相册页数:
查看:


的源码:


之前是希望通过上述代码得到总页面数'9'. 发现通过https://mm.taobao.com/self/model_album.htm?user_id=17681
7195无法获取上述Html.
只能找到加载该页面时的动态请求https://mm.taobao.com/self/album/open_album_list.htm?_charset=utf-8&user
_id%20=176817195的源码,从而得到:


老实说这种方法真的很笨。不知道有没有更简易的方式。

找到相册ID后。,通过https://mm.taobao.com/self/album_photo.htm?user_id=176817195&album_id=10000962815
点击进入相册,同样查找xhr文件,找到:https://mm.taobao.com/self/album/album_photo_list.htm?user_id=
176817195&album_id=301783179&album_flag=0,直接打开该连接源码找到:
https://mm.taobao.com/album/json/get_album_photo_list.htm?user_id=176817195&album_id=10000794223&page=1

这总算找到了相册的信息。


这个信息简直要什么有什么啊。
好了。
现在开始写程序:
#!usr/bin/env/python
#encoding:UTF-8import urllib
import requests
import json
import os
import re
import timeclass MMSpider:def __init__(self):self.__code_type = 'gbk'self.__http = 'http:'# 美人库动态加载xhr数据的urlself.__url = 'http://mm.taobao.com/tstar/search/tstar_model.do?_input_charset=utf-8'# 模特主页地址self.__person_url = 'http://mm.taobao.com/self/aiShow.htm?userId='#相册地址self.__all_album_url = 'https://mm.taobao.com/self/album/open_album_list.htm?_charset=utf-8&user_id%20='# 具体相册地址self.__pic_url = "https://mm.taobao.com/album/json/get_album_photo_list.htm?user_id="# 存储照片的基地址self.__save_path = 'F:\Beauty'# 想要获取的页数self.__total_page = 1# 当前正在提取的页数self.__currentPage = 1 # 找到具体album的id的正则表达式self.__album_id_pattern = re.compile('''<h4>.*?album_id=(.*?)&''', re.S)# album有多少的的正则表达式# 找到具体album的id的正则表达式self.__album_page_pattern = re.compile('''<input name="totalPage" id="J_Totalpage" value="(.*?)"''', re.S)#根据动态请求获取需要的第X页的json数据,找出userIddef get_person_dict(self, currentPage):try:data = {"currentPage":currentPage}data = urllib.parse.urlencode(data).encode('utf-8')request = urllib.request.Request(self.__url, data=data)response = urllib.request.urlopen(request)result = response.read().decode(self.__code_type)return json.loads(result)except urllib.error.URLError as e:print('美人动态加载信息出错',e.reason)# 根据得到的userID,找到相册的总页数def get_album_page(self, userId):try:all_album_url = self.__all_album_url+str(userId)res = urllib.request.urlopen(all_album_url)html = res.read().decode(self.__code_type)return re.search(self.__album_page_pattern, html).group(1)except urllib.error.URLError as e:print('动态加载相册总信息出错',e.reason)return None# 由得到的相册总页数范围内指定的页数,获取该页所有相册的IDdef get_album_ids(self, userId, page):try:all_album_url = self.__all_album_url + str(userId) + "&" + str(page)request = urllib.request.Request(all_album_url)response = urllib.request.urlopen(request)html = response.read().decode(self.__code_type)# 提取该页中album的idreturn re.findall(self.__album_id_pattern, html)except urllib.error.URLError as e:print("提取相册id出错了!", e.reason)# 找到一个相册内的图片有多少页def get_pic_page(self, userId, albumId):try:# 先得到这个相册一共有多少页url = self.__pic_url + str(userId) + "&album_id=" + str(albumId)response = urllib.request.urlopen(url)result = json.loads(response.read().decode(self.__code_type))return result["totalPage"]except urllib.error.URLError as e:print(e.reason)return None# 根据相册图片页数获取指定页数的图片信息def get_img_url(self, person, j, album_id):url = self.__pic_url + str(person["userId"]) \+ "&album_id=" + str(album_id) \+ "&page=" + str(j)try:response = urllib.request.urlopen(url, timeout=5)result = response.read().decode(self.__code_type)imgs_url = json.loads(result)["picList"]return imgs_urlexcept TimeoutError as e:print('1',e.strerror)except urllib.error.URLError as e:print('2',e.reason)except BaseException as e:print('3',e.args)# 保存model的个人信息def save(self, searchDOList):for person in searchDOList:dir_path = self.__save_path+'\\'+person['realName']if self.mkdir(dir_path):txt_path = dir_path+'\\'+person['realName']+'.txt'self.write_txt(txt_path, person)self.save_imgs(person,dir_path)def mkdir(self, dir_path):if(os.path.exists(dir_path)):return Falseelse:os.mkdir(dir_path)return Truedef write_txt(self,txt_path, person):person_url = self.__person_url+str(person['userId'])content = "姓名:" + person["realName"] + "  城市:" + person["city"] \+ "\n身高:" + str(person["height"]) + "  体重:" + str(person["weight"]) \+ "\n喜欢:" + str(person["totalFavorNum"]) \+ "\n个人主页:" + person_urlwith open(txt_path, 'w',encoding='utf-8')as file:print('正在保存%s的文字信息'%(person['realName']))file.write(content)file.close()def save_imgs(self, person, dir_path):album_page = self.get_album_page(person['userId'])print(album_page)img_index = 1for i in range(1, int(album_page)+1):album_ids =self.get_album_ids(person["userId"],i)for album_id in album_ids:pic_page = self.get_pic_page(person["userId"],album_id)for j in range(1, int(pic_page)+1):img_urls = self.get_img_url(person,j,album_id)for img_url in img_urls:try:url = self.__http+img_url["picUrl"]res = urllib.request.urlopen(url, timeout =5)with open(dir_path+'\\'+str(img_index)+'.jpg','wb') as file:file.write(res.read())if img_index % 10 ==0:print('sleep 1 second')time.sleep(1)if img_index>=11:print('%s已保存11张辣照'%person['realName'])file.close()returnimg_index +=1except TimeoutError as e:print('1',e.strerror)except urllib.error.URLError as e:print('2',e.reason)def start(self):print("开始!")opener = urllib.request.build_opener()opener.addheaders = [("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36")]urllib.request.install_opener(opener)for i in range(self.__total_page):dict_result = self.get_person_dict(self.__currentPage)searchDOList = dict_result["data"]["searchDOList"]# 保存所有本页中MM的信息self.save(searchDOList)self.__currentPage += 1if __name__=="__main__":spider = MMSpider()spider.start()


												

[python3.6]爬虫实战之爬取淘女郎图片相关推荐

  1. Python爬虫实战 | (9) 爬取搜狗图片

    本篇博客我们将爬取百度图片,输入搜索词,爬取与搜索词相关的图片. 首先打开搜狗图片https://pic.sogou.com/,比如搜索"猫",此时的URL如下: https:// ...

  2. python3 scrapy 爬虫实战之爬取站长之家

    爬取目标 站长之家:http://top.chinaz.com/all/ 爬取工具 win10 python3 scrapy BeautifulSoup 爬取内容 1 网站缩略图 2 网站名称 3 网 ...

  3. Python爬虫实战:爬取淘女郎照片

    本篇目标 抓取淘宝MM的姓名,头像,年龄 抓取每一个MM的资料简介以及写真图片 把每一个MM的写真图片按照文件夹保存到本地 熟悉文件保存的过程 PS:如有需要Python学习资料的小伙伴可以加下方的群 ...

  4. Python爬虫实战(1) | 爬取豆瓣网排名前250的电影(下)

    在Python爬虫实战(1) | 爬取豆瓣网排名前250的电影(上)中,我们最后爬出来的结果不是很完美,这对于"精益求精.追求完美的"程序猿来说怎么能够甘心 所以,今天,用pyth ...

  5. 携程ajax,Python爬虫实战之爬取携程评论

    一.分析数据源 这里的数据源是指html网页?还是Aajx异步.对于爬虫初学者来说,可能不知道怎么判断,这里辰哥也手把手过一遍. 提示:以下操作均不需要登录(当然登录也可以) 咱们先在浏览器里面搜索携 ...

  6. Python爬虫实战之爬取糗事百科段子

    Python爬虫实战之爬取糗事百科段子 完整代码地址:Python爬虫实战之爬取糗事百科段子 程序代码详解: Spider1-qiushibaike.py:爬取糗事百科的8小时最新页的段子.包含的信息 ...

  7. Python【爬虫实战】爬取美女壁纸资源

    Python[爬虫实战]爬取美女壁纸资源 一:首先选取一个网站,这里我们选择了一个壁纸网站 二:进入网站,我们可以看到很多图片放在一页里 三:按下F12开发者工具,点击Elments查看网页的代码 四 ...

  8. [day4]python网络爬虫实战:爬取美女写真图片(Scrapy版)

    l> 我的新书<Android App开发入门与实战>已于2020年8月由人民邮电出版社出版,欢迎购买.点击进入详情 文章目录 1.开发环境 2.第三方库 3.Scrapy简介 4. ...

  9. [day1]python网络爬虫实战:爬取美女写真图片

    l> 我的新书<Android App开发入门与实战>已于2020年8月由人民邮电出版社出版,欢迎购买.点击进入详情 文章目录 1.开发环境 2.第三方库 3.实现 1.分析url格 ...

最新文章

  1. C++ 笔记(30)— 友元函数与友元类
  2. 9.68最长公共子序列
  3. Android TextView中图文混排设置行间距导致高度不一致问题解决
  4. centos7 VNC-Server-6.7.2
  5. mysql分布式数据库中间件对比
  6. Openstack 一直在调度中解决
  7. 前端学习之BOM(浏览器对象模型)
  8. python多进程传递参数_急急急, Python 多进程,如何传递 epoll?
  9. 插入排序--Java
  10. Webpack实战(三):作为前端你不得不懂的Webpack资源入口和出口的配置
  11. Anaconda3下载失败的解决方法
  12. ArrayList ListItr
  13. 2018年Google开发者大会
  14. 2019/9/10谷歌开发者大会汇总
  15. Android应用生命周期实现简单的秒表App
  16. 【CRM】CRM开发中常用表
  17. ASP.NET Core 数据保护(Data Protection)【上】
  18. 从村上春树到cyberspace security
  19. PHP curl的DNS解析问题(PHP下curl很慢)
  20. vue:element ui分页改变pageSize,触发两次回调请求

热门文章

  1. 《Effective Java》读书笔记
  2. 20194711 阚宇航 第一次软工作业
  3. 滤波器中通带纹波、阻带纹波、通带最大波纹和阻带最小衰减
  4. 6款换脸软件下载推荐!
  5. 灰流丽能无效融合么_【灰流丽】封印卡片一览
  6. 2021-06-22Android模拟器
  7. “产教融合,共享生态” CIE 2017中国IT教育博鳌论坛圆满召开
  8. 零基础学 MySQL
  9. 微信小程序与服务器对称加解密,细说CryptoJs使用(微信小程序加密解密)
  10. 状态空间的离散时间模型