资讯专栏INFORMATION COLUMN

Scrapy 实战之爬取妹子图

Achilles / 2534人阅读

摘要:很多人学习爬虫的第一驱动力就是爬取各大网站的妹子图片,比如比较有名的。最后我们只需要运行程序,即可执行爬取,程序运行命名如下完整代码我已上传到微信公众号后台,在痴海公众号后台回复即可获取。本文首发于公众号痴海,后台回复即可获取最新编程资源。

阅读文本大概需要 10 分钟。

很多人说爬虫这门技术非常有趣,但不知道如何入门。其实爬虫入门非常简单,难的部分在于各大网站的反爬机制。当然对于一些简单的网站,还是非常容易爬取。

学习爬虫首先要明确你的驱动力,是想爬一些知乎的数据,还是一些电影的资源。驱动力非常重要,这决定你是否有足够的兴趣继续学下去。

很多人学习爬虫的第一驱动力就是爬取各大网站的妹子图片,比如比较有名的 mzitu。在爬这些网站的时候,即可以欣赏漂亮的妹子图,又能学习到技术,非常的 nice。

今天我就结合非常好用的 scrapy 框架,去抓取一些妹子图片,并把爬取的数据保存到 mongodb 数据库中。本次要爬取的网站是 360 的图片搜索网站,

地址:http://images.so.com/

360 图片的妹子质量还是非常可以的,我随意放几张大家感受下。

清纯可爱的

文艺又气质的

仙气十足的

非常的赏心悦目。

程序思路

本次程序运行的环境是 windows 10 + python 3.6,运行本次程序前首先确保你已经安装好了 scrapy、pymongo 以及 mongodb 数据库。

简单的分析了下 360 图片网站,并没有很强的反爬措施,并且网站的数据是以 Ajax 请求呈现。

我们进一步查看请求的详情,观察返回的数据结构。

返回的是 JSON 数据格式,其中 list 字段把图片的一些信息都保存在这里面。比如我们需要的图片地址信息 cover_imgurl。另外观察 Ajax 请求的参数信息,还有一个 sn 一直在变化,这个参数很明显就是偏移量。当 sn  为 30 时,返回的是前 30 张图片,依次类推,我们只需要改变 sn 的值就可以一直获取图片的信息。

接下来我们只需要通过 scrapy 高性能的框架,把网站上的图片保存到本地即可。

新建项目

首先在本地创建一个 scrapy 项目并命名为 images360。通过已下的命名即可创建。

scrapy startproject images360

随后就会有如下的项目结构

接下来就是在 spiders 目录下新建一个 Spider,命令如下:

scrapy genspider images images.so.com

这样我们的项目都已创建好,最后项目的结构如下。

程序代码

settings.py

在 settings.py 里面会先定义一个变量 MAX_PAGE,表示我们需要爬取的最大页面,比如在此次的程序中我们设置的是 50,也就是爬取 50 页,每页 30 张,一共 1500 张图片。

MAX_PAGE = 50

settings.py 文件中我们还设置一些数据库相关的配置信息。

MONGO_URI = "localhost"
MONGO_DB = "test"
IMAGES_STORE = "./images"

并且需要注意的是我们要修改 settings.py 中的 ROBOTSTXT_OBEY 变量,将其设置为 False,否则无法抓取。

ROBOTSTXT_OBEY = False

start_requests()

这个函数用来构造最开始的请求,用来生成 50 次请求。

    def start_requests(self):
        data = {"ch": "photogtaphy", "listtype": "new"}
        base_url = "https://image.so.com/zj?0"
        for page in range(1, self.settings.get("MAX_PAGE") + 1):
            data["sn"] = page * 30
            params = urlencode(data)
            url = base_url + params
            yield Request(url, self.parse

提取信息

我们会在 items.py 文件中定义一个 Images360Item 类,用来定义我们的数据结构。

class Images360Item(Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    collection = table = "images"
    id = Field()
    url = Field()
    title = Field()
    thumb = Field()

其中包括图片的 ID、链接、标题、缩略图。另外还有两个属性 collection 和 table,都定义为 images 字符串,代表 MongoDB 存储的 Collection 名称。

接下来我们提取 Spider 里有关信息,在 parse() 方法改写成如下所示:

    def parse(self, response):
        result = json.loads(response.text)
        for image in result.get("list"):
            item = Images360Item()
            item["id"] = image.get("imageid")
            item["url"] = image.get("qhimg_url")
            item["title"] = image.get("group_title")
            item["thumb"] = image.get("qhimg_thumb_url")
            yield item

这样我们就完成了信息的提取,接下来就需要把抓取的信息保存到 MongoDB 中。

MongoDB

首先确保你本地已经安装好了 MongoDB,并且已经正常启动。我们用一个 MongoPipeline 将信息保存到 MongoDB 中,在 pipelines.py 里添加如下类的实现:

class MongoPipeline(object):
    def __init__(self, mongo_uri, mongo_db):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            mongo_uri=crawler.settings.get("MONGO_URI"),
            mongo_db=crawler.settings.get("MONGO_DB")
        )

    def open_spider(self, spider):
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client[self.mongo_db]

    def process_item(self, item, spider):
        self.db[item.collection].insert(dict(item))
        return item

    def close_spider(self, spider):
        self.client.close()

Scrapy 提供了专门处理下载的 Pipeline,包括文件下载和图片下载。下载文件和图片的原理与抓取页面的原理一样,因此下载过程支持异步和多线程,下载十分高效。

我们首先在 settings.py 定义一个 IMAGES_STORE 变量,用来表示图片存储的路径。

IMAGES_STORE = "./images"

内置的 ImagesPipeline 会默认读取 Item 的 image_urls 字段,并认为该字段是一个列表形式,它会遍历 Item 的 image_urls 字段,然后取出每个 URL 进行图片下载。

但是现在生成的 Item 的图片链接字段并不是 image_urls 字符表示的,也不是列表形式,而是单个的 URL。所以为了实现下载,我们需要重新定义下载的部分逻辑,即要自定义 ImagePipeline,继承内置的 ImagesPipeline,从而实现我们自己的图片下载逻辑。

class ImagePipeline(ImagesPipeline):
    def file_path(self, request, response=None, info=None):
        url = request.url
        file_name = url.split("/")[-1]
        return file_name

    def item_completed(self, results, item, info):
        image_paths = [x["path"] for ok, x in results if ok]
        if not image_paths:
            raise DropItem("Image Downloaded Failed")
        return item

    def get_media_requests(self, item, info):
        yield Request(item["url"])

最后我们需要在 settings.py 中把我们定义好的 Item Pipeline 打开,修改 settings.py 中的 ITEM_PIPELINES 即可。

ITEM_PIPELINES = {
   "images360.pipelines.ImagePipeline": 300,
   "images360.pipelines.MongoPipeline": 301
}

最后我们只需要运行程序,即可执行爬取,程序运行命名如下:

scrapy crawl images

完整代码我已上传到微信公众号后台,在「痴海」公众号后台回复「360」即可获取。

本文首发于公众号「痴海」,后台回复「1024」即可获取最新编程资源。

比如这样的:史上最全 Python 学习资料,PDF 电子书大合集

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/44852.html

相关文章

  • 首次公开,整理12年积累的博客收藏夹,零距离展示《收藏夹吃灰》系列博客

    摘要:时间永远都过得那么快,一晃从年注册,到现在已经过去了年那些被我藏在收藏夹吃灰的文章,已经太多了,是时候把他们整理一下了。那是因为收藏夹太乱,橡皮擦给设置私密了,不收拾不好看呀。 ...

    Harriet666 评论0 收藏0
  • 零基础如何学爬虫技术

    摘要:楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,。本文来源知乎作者路人甲链接楚江数据提供网站数据采集和爬虫软件定制开发服务,服务范围涵盖社交网络电子商务分类信息学术研究等。 楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,http://www.chujiangdata.com。 第一:Python爬虫学习系列教程(来源于某博主:htt...

    KunMinX 评论0 收藏0
  • Python爬虫 - scrapy - 爬取妹子 Lv2

    摘要:前言这个文章是延续之前爬取妹子图的延续,之前的爬虫可以爬取一个页面的图片,爬取一次大概张图片的样子,按照之前的计划,本次要进一步完善爬虫,爬取妹子图全网图片。做完上述改动后,爬虫运行基本正常,但是爬取的速度有点慢,个小时大概爬取了张图片。 0. 前言 这个文章是延续之前《爬取妹子图 Lv1》的延续,之前的爬虫可以爬取一个页面的图片,爬取一次大概400张图片的样子,按照之前的计划,本次要...

    Backache 评论0 收藏0
  • scrapy简单学习5—片下载,爬取妹子

    摘要:学习网站爬虫,整站爬取妹子图定义爬取的内容的编写提供了一种便捷的方式填充抓取到的是页面源代码,载入每个连接,用属性请求连接,返回请求获取页码集合打印页码如果页码集合图片连接读取页码集合的倒数第二个页码图片连接替换成空返回请求用载 学习网站:爬虫,整站爬取妹子图 1.item.py(定义爬取的内容) import scrapy class MeizituItem(scrapy.Ite...

    JerryZou 评论0 收藏0
  • Python爬虫 - scrapy - 爬取妹子 Lv1

    摘要:爬取妹子图的实例打算分成三部分来写,尝试完善实用性。中的每一个子项都是一个标签。这个说明的前提是不自定义当爬虫完成的模型数据采集后,会自动将发送给处理。 0. 前言 这是一个利用python scrapy框架爬取网站图片的实例,本人也是在学习当中,在这做个记录,也希望能帮到需要的人。爬取妹子图的实例打算分成三部分来写,尝试完善实用性。 系统环境 System Version:Ubunt...

    el09xccxy 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<