美文网首页
Python Scrapy第一弹--爬取好看的堆糖头像

Python Scrapy第一弹--爬取好看的堆糖头像

作者: 不存在的一角 | 来源:发表于2018-12-09 01:00 被阅读28次

目标爬取堆糖头像,适合练手

堆糖的图片是真的好看啊,虽然女性用户较多,但是真的好看!所以想抓些头像来,这样子就不用愁换头像啦!

因为要爬取大量的图片,所以这次用的是python的scrapy框架,正好熟悉一下强大的scrapy

由于我的电脑上同时装了Python2和Python3,所以创建scrapy项目时需要注意,有问题的朋友可以参考我之前的一篇博文:解决scrapy创建项目时报错

爬取思路

首先来到堆糖的头像界面:
https://www.duitang.com/search/?kw=%E5%A4%B4%E5%83%8F&type=feed#!s

这里写图片描述

计算了一下,每页有24张头像图片,共30页,打开Chrome的开发者工具,往下滑动界面,我们发现这些图片是通过异步加载出来的


这里写图片描述

这是我们还可以看到浏览器通过向这个URL发送请求得到了这些图片


这里写图片描述

所以我们只需要模仿浏览器发送这个请求就能拿到图片啦:

https://www.duitang.com/napi/blog/list/by_search/?kw=%E5%A4%B4%E5%83%8F&type=feed&include_fields=top_comments%2Cis_root%2Csource_link%2Citem%2Cbuyable%2Croot_id%2Cstatus%2Clike_count%2Csender%2Calbum&_type=&start=24&_=1529059499009

分析URL

可以看到URL最后的参数中有<font color=#8B0000> start=24</font>,以及 <font color=#8B0000>_=1529059499009</font>
<font color=#8B0000>start</font>很好分析,对应的是起始的第几张图,而 <font color=#8B0000>"_="</font>后面的数字串,熟悉的人可以一眼看出是一个时间戳

所以大致思路就出来了,我们可以重写start_requests()方法,利用format将start以及时间戳传入,再循环请求即可:

具体代码

代码如下:

# -*- coding: utf-8 -*-
import scrapy
import json
import time
import datetime
from DuiTang.items import DuitangItem

'''
https://www.duitang.com/search/?kw=%E5%A4%B4%E5%83%8F&type=feed
https://www.duitang.com/search/?kw=%E5%A4%B4%E5%83%8F&type=feed#!s 第一页 120张 24*5
https://www.duitang.com/search/?kw=%E5%A4%B4%E5%83%8F&type=feed#!s-p2 第二页

'''

class DuitangSpider(scrapy.Spider):
    name = 'duitang'
    allowed_domains = ['www.duitang.com']
    start_urls = ['http://www.duitang.com/']
    image_api_url = 'https://www.duitang.com/napi/blog/list/by_search/?kw=%E5%A4%B4%E5%83%8F&type=feed&include_fields=top_comments%2Cis_root%2Csource_link%2Citem%2Cbuyable%2Croot_id%2Cstatus%2Clike_count%2Csender%2Calbum&_type=&start={}&_={}'

    def start_requests(self):
        #记录时间戳为x
        x = int(round(time.time() * 1000))
        #range(0,150)
        for i in range(0,15):
            start = i*24
            image_api_url = self.image_api_url.format(start,x)
            x += 1
            yield scrapy.Request(url=image_api_url,callback=self.parse)

    def parse(self, response):
        item = DuitangItem()
        #将其转换为json格式
        image_info = json.loads(response.text)
        for i in image_info['data']['object_list']:
            item['photo_path'] = i['photo']['path']
            item['id'] = i['id']
            yield item

将获取到的item在<font color= #1E90FF>pipeline.py</font>中进行进一步操作,把图片保存到本地

import os
import requests

class DuitangPipeline(object):
    def process_item(self, item, spider):
        image_url = item['photo_path']
        print image_url
        r = requests.get(image_url)
        #注意打开文件方式为‘wb’
        f = open('D:\Python\PycharmProject\Enhance\DuiTang\image\{}.jpeg'.format(item['id']),'wb')
        f.write(r.content)
        f.close()
        return item

以及<font color= #1E90FF>itempy</font>

from scrapy import Item,Field
import scrapy


class DuitangItem(Item):
    photo_path = scrapy.Field()
    id = scrapy.Field()

注意在<font color= #1E90FF>setting.py</font>中启动管道中间件以及请求头,同时可以设置下载时延等,避开反爬

遇到的问题

最奇葩的是在下载完图片后发现图片损坏严重,呈彩条状!
结果翻了几篇博客都没什么想法,最后还是检查了一边,发现

f = open('D:\Python\PycharmProject\Enhance\DuiTang\image\{}.jpeg'.format(item['id']),'w')

w 没有改成 wb!!!,再次被自己蠢哭....

最后若有疑问欢迎交流


print('微信公众号搜索 "猿狮的单身日常" ,Java技术升级、虫师修炼,我们 不见不散!')
print('也可以扫下方二维码哦~')
猿狮的单身日常

相关文章

网友评论

      本文标题:Python Scrapy第一弹--爬取好看的堆糖头像

      本文链接:https://www.haomeiwen.com/subject/iwxhhqtx.html