社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python爬虫 - scrapy - 爬取妹子图 Lv1

唤之 • 7 年前 • 984 次点击  

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名字是可以改的,但是imagesimage_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,那么在spider完成item采集后,Scrapy会自动开启系统默认的ImagesPipeline处理通道,这也是之前定义item的时候,imagesimage_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://www.jintiankansha.me/t/H7HzmgP8Pm
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/7414