利用scrapy 爬取煎蛋网图片

hresh 548 0

利用scrapy 爬取煎蛋网图片

Python爬虫内容都是于2019上半年写的,关于某些网站的爬取技巧可能已经过时了,仅供参考。

scrapy 图片下载,自定义图片名称

学习 Scrapy 过程中发现用 Scrapy 下载图片时,总是以他们的 URL 的 SHA1 hash 值为文件名,如:

图片 URL:http://www.example.com/image.jpg

它的 SHA1 hash 值为:3afec3b4765f8f0a07b78f98c07b83f013567a0a

则下载的图片为:3afec3b4765f8f0a07b78f98c07b83f013567a0a.jpg

目的是下载的图片为:image.jpg或者xxx.jpg

可以通过编写 Pipeline 来实现。

1. 创建 scrapy 工程
进入目录下:
shift 键+鼠标右键,打开 dos 窗口

scrapy startproject airi_pic
目录结构<br>airi_pic.
│ scrapy.cfg
│
└─airi_pic
    │ items.py
    │ pipelines.py
    │ settings.py
    │ __init__.py
    │
    └─spiders
           __init__.py

2. 在 items.py 中定义需要爬取信息的变量名称

import scrapy

#爬取煎蛋网图片
class JiandanPicItem(scrapy.Item):
    image_url = scrapy.Field()
    image_name = scrapy.Field()

3. 在 spiders 目录下创建 jiandan_pic_spider.py 文件,代码如下

import scrapy
from airi_pic.items import JiandanPicItem
import base64

Page = 0
class JiandanPicSpider(scrapy.Spider):

    name = 'jiandan_pic'

    start_urls = ['http://jandan.net/ooxx/page-1#comments']

    def parse(self, response):
        global Page
        sel = scrapy.Selector(response)

        image_urls = sel.xpath(
            '//ol[@class="commentlist"]//div[@class="row"]/div[@class="text"]//span[@class="img-hash"]/text()').extract()#爬取到的html和实际略有出入
        image_names = sel.xpath(
            '//ol[@class="commentlist"]//div[@class="row"]/div[@class="text"]/span[@class="righttext"]/a/text()').extract()

        new_urls = []
        for xx in image_urls:  # 获取的url需要转换编码
            url = base64.b64decode(xx).decode('utf-8')
            new_urls.append('https:' + url)

        item = JiandanPicItem()
        item['image_url'] = new_urls
        item['image_name'] = image_names

        yield item

        while Page < 2:#控制爬取的页数
            next_page = response.xpath('//div[@class="cp-pagenavi"]/a[@class="next-comment-page"]/@href')#获取“下一页"的具体网址
            if next_page:
                url = response.urljoin(next_page[0].extract())
                yield scrapy.Request(url, self.parse)
            Page += 1

4. 下载图片需要配置 pipelines 文件

from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem
from scrapy import Request

class JiandanPicPipeline(ImagesPipeline):
    def file_path(self, request, response=None, info=None):
        item = request.meta.get('item')#注意注意注意!!!,这里有坑,不能再使用request.meta['item']
        index = request.meta.get('index')
        # print(request.url)
        # print(index)
        image_name = item['image_name'][index] + '.' + request.url.split('/')[-1].split('.')[-1]
        file_name = "{0}/{1}".format('jiandan',image_name)

        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('图片未下载好')
        return item

    def get_media_requests(self, item, info):
        for image_url in item['image_url']:
            yield Request(image_url, meta={'item': item, 'index': item['image_url'].index(image_url)})

****5.settings.py****

ITEM_PIPELINES={
    # 'airi_pic.pipelines.AiriPicPipeline':1
    'airi_pic.pipelines.JiandanPicPipeline':1
}
IMAGES_STORE='pic'#图片保存目录路径

IMAGES_EXPIRES = 90

****6. 与 scrapy.cfg 同级目录下新建 start.py****

from scrapy import cmdline

cmdline.execute("scrapy crawl jiandan_pic".split(' '))

运行 start.py 文件即可。

发表评论 取消回复
表情 图片 链接 代码

分享