Scrapy爬女神图(一)—— 这是你们要的小姐姐

浏览: 2243

  


看到这个标题,目测一大波老司机心里开始os:难道又是 妹子图???

(我。。。我还能说什么)

宝宝的品位可不一般的好吧!!!
这年代最流行什么呀?
当然是“女神”,“校花”啦!!!(额,说“网红”的当我没说。。)
颜值高,有范儿,关键气质逆天对不对~

比如这样:


这样:


或者这样:


这样:


不错吧?(嘿嘿据说最后这个还是我川的妹子~)心动不如行动,今天我们就用Scrapy把诸位女神收入囊中!
目标网站:唯一图库
搜索关键词:校花

一、步骤

1、首先分析网站
打开上面这个页面



                                                                                           下拉就是各位MM的简介



                                                                                                                                下拉到最底部就是这样



点完之后发现,真的只有6页。


查看源代码


随便点击进入某个主页




查看源码

看完第一个图,来看后面的图



第二个图是这样


第三个图是这样


可以看出规律了吧,皆是是 url=xxx+_n.html(n为1,2,3...)的结构,只要获得前面那一串和最大页数就可以构造了。

但是进一步分析就会发现,每个MM个人页面内图片的URL结构是不一样的(这里也要注意),如下所示:




基本上无规律可循,不能构造出来,只能从源码中获取图片真实链接

2、思路
用Scrapy爬取思路:
1)先获取首页siteURL,以及标题
2)然后由其进入MM个人页面获取最大页数Num和第一个图片URL
3)构造每一个图片地址pageURL
4)requests获取源码中具体原图地址detailURL
5)获取图片并保存入文件,以1)中标题作为文件名

这里就涉及到了多层次页面爬取的问题
怎么办呢,不要忘了,可以用meta传参数。

二、代码

首先来看整个项目的文件结构
以为没有本项目用到middlewares中间件,所以删去了


entrypoint是一个设置,使得程序可以在IDE中运行。
只需要调用entrypoint即可运行程序

from scrapy.cmdline import execute
execute(['scrapy', 'crawl', 'XiaoHua'])

来看具体分块代码实现:

1、items部分

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy

class XiaohuaItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
siteURL=scrapy.Field() #首页中各MM的URL
pageURL=scrapy.Field() #每一张图片入口URL
detailURL=scrapy.Field() #图片原图地址
title=scrapy.Field() #MM标题
fileName=scrapy.Field() #文件夹名,每一个MM一个文件夹
path=scrapy.Field() #图片存储路径(绝对路径)

2、settings部分

# -*- coding: utf-8 -*-
# Scrapy settings for XiaoHua project

BOT_NAME = 'XiaoHua'
SPIDER_MODULES = ['XiaoHua.spiders']
NEWSPIDER_MODULE = 'XiaoHua.spiders'

#是否遵循机器人规则
ROBOTSTXT_OBEY = False
#默认是16,一次可以请求的最大次数
CONCURRENT_REQUESTS=32
#下载延迟
DOWNLOAD_DELAY=0.1
#Cookies设置
COOKIES_ENABLED = False
#headers设置
DEFAULT_REQUEST_HEADERS = {
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding':'gzip, deflate, sdch',
'Accept-Language':'zh-CN,zh;q=0.8',
'Cache-Control':'max-age=0',
'Connection':'keep-alive',
'User-Agent':'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'}

#管道设置
ITEM_PIPELINES = {'XiaoHua.pipelines.XiaohuaPipeline': 300}

3、spiders部分

# --coding:utf-8--
import scrapy
from XiaoHua.items import XiaohuaItem
from scrapy.http import Request
import requests
import re
import os
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

class Myspider(scrapy.Spider):
name='XiaoHua'
allowed_domains=['mmonly.cc']
base=r'F:/Desktop/code/info/XiaoHua/'
def start_requests(self):
#一共有6页
for i in range(1,7):
url='https://www.mmonly.cc/tag/xh1/'+str(i)+'.html'
yield Request(url,callback=self.parse_one)

def parse_one(self,response):
#创建一个大的list存储所有的item
items=[]
pattern=re.compile(r'<div class="title".*?<a.*?href="https://ask.hellobi.com/(.*?)">(.*?)</a></span></div>',re.S)
mains=re.findall(pattern,response.text)
for main in mains:
#创建实例,并转化为字典
item=XiaohuaItem()
item['siteURL']=main[0]
item['title']=main[1]
item['fileName']=self.base+item['title']
items.append(item)

for item in items:
#创建文件夹
fileName=item['fileName']
if not os.path.exists(fileName):
os.makedirs(fileName)
#用meta传入下一层
yield Request(url=item['siteURL'],meta={'item1':item},callback=self.parse_two)

def parse_two(self,response):
#传入上面的item1
item2=response.meta['item1']
source=requests.get(response.url)
html=source.text.encode('utf-8')
#用正则提取页数
pattern=re.compile(r'共(.*?)页',re.S)
Num=re.search(pattern,html).group(1)
items=[]
for i in range(1,int(Num)+1):
#注意这里,创建实例的位置
item=XiaohuaItem()
item['fileName']=item2['fileName']
#构造每一个图片的存储路径
item['path']=item['fileName']+'/'+str(i)+'.jpg'
#构造每一个图片入口链接,以获取源码中的原图链接
item['pageURL']=response.url[:-5]+'_'+str(i)+'.html'
items.append(item)
for item in items:
yield Request(url=item['pageURL'],meta={'item2':item},callback=self.parse_three)

def parse_three(self,response):
item=XiaohuaItem()
#传入上面的item2
item3=response.meta['item2']
#匹配正则获取图片真实地址detailURL
pattern=re.compile(r'<li class="pic-down h-pic-down"><a target="_blank" class="down-btn" href=\'(.*?)\'>.*?</a>',re.S)
URL=re.search(pattern,response.text).group(1)
item['detailURL']=URL
item['path']=item3['path']
item['fileName']=item3['fileName']
yield item

4、pipelines部分

# -*- coding: utf-8 -*-
import requests
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

#用requests的get方法获取图片并保存入文件
class XiaohuaPipeline(object):
def process_item(self, item, spider):
detailURL=item['detailURL']
path=item['path']
fileName=item['fileName']

image=requests.get(detailURL)
f=open(path,'wb')
f.write(image.content)
f.close()
print u'正在保存图片:',detailURL
print u'图片路径:',path
print u'文件:',fileName
return item

写完代码,直接调用entrypoint即可在IDE中运行(我用的Pycharm)
这个小项目我也放到github上了:https://github.com/LUCY78765580/Python-web-scraping/tree/master/XiaoHua (如果您觉得有帮助,可以star我哟~)

三、结果

最后结果就是这样的:



一共抓取图片2114张


文件是这样



随便打开是这样

四、参考:

meta传参这一块,参考了博客:
http://www.jianshu.com/p/c77c59aa4b92

五、我分享我快乐

这里是你们要的小姐姐^_^:

百度网盘:https://pan.baidu.com/s/1bpxPRen
密码:25gq

下载下来稍稍解压即可,不用太感谢(顺手点个赞就行),我是造福人类的小天使~

六、总结

最后,总结本篇关键:
1、Scrapy爬取多级网页结构(主要用meta传递数据)
2、Scrapy爬取图片的一般方法(别的方法放下次讨论)
对了,不知各位有没有发现,我们在爬唯一图库时,竟然如此顺利,没有遇到任何反爬。感叹:良心网站呀

推荐 9
本文由 waking_up88688 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

2 个评论

好东西
哈哈哈,拿走不谢

要回复文章请先登录注册