Python 3实战Scrapy爬取妹子图

简介

本文不是零基础教程,你需要对Python/Python 3的基本语法和特性有一定了解,需知道如何使用pip安装所需库!推荐使用 PyCharm IDE开发

实战

得益于强大的scrapy框架,写个简单的爬虫还是很容易的,但是如果想写的通用和健全还是挺难的,不过对于爬图片来说,相对来说更简单,简单粗暴的做法就是爬取页面所有图片,然后在爬取页面所有a链接,再去这些a链接页面爬取所有图片,递归获取...但是这样容易陷入死循环,不过强大的scrapy框架有一个设置爬取深度的选项,设置一下即可!
直接上代码吧,scrapy框架的基本用法我就不介绍,这里只做一些关键点解析,请注意查看注释:

# -*- coding:utf-8 -*-
# ! /bin/bash/python3

from urllib.parse import urljoin
from scrapy.spiders import Spider
from scrapy.http import Request
from picScrapy.items import PicscrapyItem

class PicSpider(Spider):
    name = "pic"  # 定义爬虫名,启动爬虫的时候用到
    start_url = 'http://www.win4000.com/wallpaper_2285_0_10_1.html'  # 爬虫入口
    # 设置爬虫的请求头,防止爬取失败
    headers = {
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 '
                      '(KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36',
    }
    def start_requests(self):
        # 据观察,爬取的页面url是有规律的,后面的数字从1到167变化
        for i in range(1, 167):
            url = 'http://www.win4000.com/wallpaper_2285_0_10_%d.html' % i
            yield Request(url, headers=self.headers)

    def parse(self, response):
        item = PicscrapyItem()
        # 获取页面所有的img标签地址,待下载
        item['image_urls'] = response.xpath('//img/@src').extract()
        yield item

        # 提取界面所有的url,待爬取
        all_urls = response.xpath('//a/@href').extract()

        # 遍历获得的url,如果满足条件,继续爬取
        for url in all_urls:
            url = urljoin(self.start_url, url)
            yield Request(url, callback=self.parse)

下载图片

上面的代码获取了页面所有img标签地址存在一个item对象里面,这个对象会被传递到pipelines里面进行处理,这里下载也是用到框架的组件,做了一些自定义设置:

# -*- coding: utf-8 -*-
import hashlib
import re
from scrapy.pipelines.images import ImagesPipeline
from scrapy import Request
from scrapy.utils.python import to_bytes

class PicscrapyPipeline(ImagesPipeline):
    def get_media_requests(self, item, info):
        for url in item['image_urls']:
            # 做了一下判断,排除一些无效链接
            if re.match(r'http', url):
                yield Request(url)

    # 重新定义了一下存储路径,默认情况下是存在一个full文件夹里面
    def file_path(self, request, response=None, info=None):
        if not isinstance(request, Request):
            url = request
        else:
            url = request.url
        image_guid = hashlib.sha1(to_bytes(url)).hexdigest()  # change to request.url after deprecation
        return '%s.jpg' % image_guid

图片下载存储路径在settings里面配置,还可以配置图片大小,过滤掉不符合条件的图片

# 爬取深度
DEPTH_LIMIT = 3
# 图片存放位置
IMAGES_STORE = '/home/jwang/Videos/Pic'
# 图片最小宽度
IMAGES_MIN_WIDTH = 500
# 图片最小高度
IMAGES_MIN_HEIGHT = 500

还有一些选项需要注意:

# 下载延迟,别把别人人站点拖垮了,慢点
DOWNLOAD_DELAY = 0.2
# 爬虫并发数,默认是 16
CONCURRENT_REQUESTS = 20

最后,启动爬虫,收获一堆妹子..图

python3 -m scrapy crawl pic --loglevel INFO

本人也是初学Python,写爬虫纯属娱乐,欢迎各位交流,代码在github上,地址如下:
代码GitHub地址

推荐阅读更多精彩内容