0. 前言
这是一个利用python scrapy框架爬取网站图片的实例,本人也是在学习当中,在这做个记录,也希望能帮到需要的人。爬取妹子图的实例打算分成三部分来写,尝试完善实用性。
系统环境
System Version:Ubuntu 16.04
Python Version:3.5.2
Scrapy Version:1.5.0
1. 建立Scrapy项目(略)
可参考《Python爬虫 - scrapy - 爬取豆瓣电影TOP250》
我建立的项目名称为:spider_meizitu
2. items文件
<项目目录>/spider_meizitu/items.py
import scrapy
class SpiderMeizituItem(scrapy.Item):
images = scrapy.Field()
image_urls = scrapy.Field()
注意:这里的SpiderMeizituItem
名字是可以改的,但是images
和image_urls
两个变量名称暂时不要改,原因后面说。
3. 爬虫文件
3.1 完整文件
<项目目录>/spider_meizitu/spiders/meizitu.py
from scrapy import Request
from scrapy.spiders import Spider
from spider_meizitu.items import SpiderMeizituItem
class MeizituSpider(Spider):
#爬虫名称
name = 'meizitu'
#开始的url
start_urls = {
'http://www.meizitu.com/a/sexy.html'
}
#处理函数
def parse(self, response):
meizi_titles = response.xpath('//ul[@class="wp-list clearfix"]/li')
for meizi_title in meizi_titles:
meizi_url = meizi_title.xpath('.//h3[@class="tit"]/a/@href').extract()[0]
yield Request(meizi_url,callback=self.parse_meizi_pic)
#处理函数跳转
def parse_meizi_pic(self,response):
item = SpiderMeizituItem()
meizitu_pics = response.xpath('//div[@id="picture"]/p/img')
for meizitu_pic in meizitu_pics:
item['images'] = meizitu_pic.xpath('.//@alt').extract()[0].split(',')[0]
item['image_urls'] = meizitu_pic.xpath('.//@src').extract()
yield item
3.2 详细说明
name和start_urls就不说了,略过。
parse函数
首先看一下妹子图网站的结构,打开我们的start_urls
。
前端页面源码:
可以看到,所有的图片项目是在一个<ul>
标签下的<li>
标签。而每个图片的链接打开后会进入一个新的页面,那里才是我们要下载的图片。所以,第一步,要解析这些页面链接,下面这段代码建立了一个<li>
标签的集合。
meizi_titles = response.xpath('//ul[@class="wp-list clearfix"]/li')
meizi_titles
中的每一个子项都是一个<li>
标签。接下来在meizi_titles
集合中做迭代循环,继续解析<li>
标签中的内容。
for meizi_title in meizi_titles:
看下<li>
标签中的源码:
注意,第一个img连接中的limg.jpg只是缩略图,并不是我们想要的内容。<h3>
标签中的连接才是后面的页面,我们要把这个链接解析出来。
meizi_url = meizi_title.xpath('.//h3[@class="tit"]/a/@href').extract()[0]
解析完成后,我们要爬虫请求新的页面,那里才有我们需要的图片:
yield Request(meizi_url,callback=self.parse_meizi_pic)
这里的callback
参数将页面请求结果发送给了当前class
下面的parse_meizi_pic
函数。解析过程与前面的页面大同小异,不细说了。
唯一需要说明的是item['image_urls']
中存储的变量必须是list
类型的,如果不是,后期在pipeline处理时会报错,无法解析url。(这个说明的前提是不自定义 ImagesPipeline
)
当爬虫完成item的模型数据采集后,scrapy会自动将item发送给Pipeline处理。
4. settings.py
<项目目录>/spider_meizitu/settings.py
需要修改的项目
ITEM_PIPELINES = {
'scrapy.contrib.pipeline.images.ImagesPipeline': 1,
}
#图片存储路径,根据自己的情况修改
IMAGES_STORE = '/home/sftp_root/spider_meizitu/meizitu'
#一些USER_AGENT
USER_AGENT_LIST = [
'zspider/0.9-dev http://feedback.redkolibri.com/',
'Xaldon_WebSpider/2.0.b1',
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0) AddSugarSpiderBot www.idealobserver.com',
"Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) Speedy Spider (http://www.entireweb.com/about/search_tech/speedy_spider/)',
'Mozilla/5.0 (compatible; Speedy Spider; http://www.entireweb.com/about/search_tech/speedy_spider/)',
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
"Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
"Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/60.0.3112.113 Chrome/60.0.3112.113 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.2372.400 QQBrowser/9.5.11096.400',
'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0'
'Nusearch Spider (www.nusearch.com)',
'nuSearch Spider (compatible; MSIE 4.01; Windows NT)',
'lmspider (lmspider@scansoft.com)',
'lmspider lmspider@scansoft.com',
'hl_ftien_spider_v1.1',
'hl_ftien_spider',
'everyfeed-spider/2.0 (http://www.everyfeed.com)',
'envolk[ITS]spider/1.6 (+http://www.envolk.com/envolkspider.html)',
'envolk[ITS]spider/1.6 ( http://www.envolk.com/envolkspider.html)',
'Baiduspider+(+http://www.baidu.com/search/spider_jp.html)',
'Baiduspider+(+http://www.baidu.com/search/spider.htm)',
'BaiDuSpider',
]
#随机发送UserAgent
DOWNLOADER_MIDDLEWARES = {
'spider_meizitu.middlewares.RandomUserAgentMiddleware': 400,
}
#每次下载图片的延迟时间
DOWNLOAD_DELAY = 3
特别需要说明的是ITEM_PIPELINES
参数。如果你看过其他的下载图片的爬虫文章,应该注意到我没有写自己的Pipeline。如果将ITEM_PIPELINES
内容指定为scrapy.contrib.pipeline.images.ImagesPipeline
,那么在spide
r完成item
采集后,Scrapy会自动开启系统默认的ImagesPipeline
处理通道,这也是之前定义item
的时候,images
和image_urls
两个参数名称不能更改的原因。具体内容可参考官方文档下载项目图片章节
5. middlewares.py
<项目目录>/spider_meizitu/middlewares.py
from spider_meizitu.settings import USER_AGENT_LIST
import random
class RandomUserAgentMiddleware():
def process_request(self, request, spider):
ua = random.choice(USER_AGENT_LIST)
if ua:
request.headers.setdefault('User-Agent', ua)
在这个实例中,middlewares的唯一功能就是想web服务器发送随机的USER_AGENT
6. 执行结果
后续计划
- Lv2 爬取多页面的妹子图
- Lv3 尝试更改图片文件名,并分目录存储
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。