乐之之

知而行乐,乐而行之,天道酬勤,学无止境。
scrapy框架图片爬取案例——以堆糖网为例

本节主要分享的是scrapy框架中关于图片类的简单爬取方法,在这里只需要用到三个文件:

1.setting.py进行scrapy抓取图片所用到的基础。

2.duitang_spider.py实现获取多出url进行翻页和数据处理。

3.pipelines.py对图片链家发起请求获取,设置图片名称,然后在管道中保存图片。

一、scrapy基础设置

  • scrapy文件框架概览

(1)setting设置

1.robots协议

ROBOTSTXT_OBEY = False

2.日志设置

LOG_LEVEL="ERROR"

3.添加user-agent

USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'

4.管道

  • 打开管道,后面对图片链接的保存、图片名设置会用到。
ITEM_PIPELINES = {
   'duitang.pipelines.DuitangPipeline': 300,
   'duitang.pipelines.ImagePipeline': 301,
}

5.文件夹创建

IMAGES_STORE="./图片"

(2)items设置

  • 在后续保存进item字典数据时会用到,在这里我们进行图片链接抓取所以只设置一个数据就可以了。
href = scrapy.Field()

二、基本代码实现

(1)duitang_spider.py

由于观察到堆糖网的数据都是Ajax加载,添加参数即可实现。

1.基础url设置

  • 堆糖链接是需要参数的,我们这里先把参数去掉,在后面循环添加进行翻页。
class DuitangSpiderSpider(scrapy.Spider):
    name = 'duitang_spider'
    allowed_domains = ['www.duitang.com']
    image_page="https://www.duitang.com/napi/blogv2/list/by_search/?"
    start_urls = ['https://www.duitang.com/search/?kw=%E7%BE%8E%E5%A5%B3&type=feed']
  • 爬取前20页数据
  • 这里观察到只有“after_id”参数在变,规律是递增乘以24。所以在这里直接循环添加就可以了。
        def parse(self, response,**kwargs):
            for num in range(20):
                data={
                         "kw": "美女",
                         "after_id": num*24,
                         "type": "feed",
                         "include_fields": 'top_comments,is_root, source_link, item, buyable, root_id, status, like_count, like_id, sender, album, reply_count, favorite_blog_id',
                        "_type":"",
                        "_": "1677407450111",
                }
                url=self.image_page+urlencode(data)
                yield scrapy.Request(url=url,callback=self.get_data)

2.数据抓取

  • 将url返回后交给self.get_data函数进行数据抓取
  • 先将数据转为json字符串,再进行循环传入。
    def get_data(self,response):
        data_list=json.loads(response.text)["data"]["object_list"]
        for data in data_list:
            item=DuitangItem()
            item["href"]=data["photo"]["path"]
            yield item
  • 到这里就duitang_spider.py就结束了,剩下的交给管道进行保存就可以了。完整duitang_spider.py代码如下:
    import scrapy
    import json
    from urllib.parse import urlencode
    from duitang.items import DuitangItem
    class DuitangSpiderSpider(scrapy.Spider):
        name = 'duitang_spider'
        allowed_domains = ['www.duitang.com']
        image_page="https://www.duitang.com/napi/blogv2/list/by_search/?"
        start_urls = ['https://www.duitang.com/search/?kw=%E7%BE%8E%E5%A5%B3&type=feed']
    
        def parse(self, response,**kwargs):
            for num in range(20):
                data={
                         "kw": "美女",
                         "after_id": num*24,
                         "type": "feed",
                         "include_fields": 'top_comments,is_root, source_link, item, buyable, root_id, status, like_count, like_id, sender, album, reply_count, favorite_blog_id',
                        "_type":"",
                        "_": "1677407450111",
                }
                url=self.image_page+urlencode(data)
                yield scrapy.Request(url=url,callback=self.get_data)
    
        def get_data(self,response):
            data_list=json.loads(response.text)["data"]["object_list"]
            for data in data_list:
                item=DuitangItem()
                item["href"]=data["photo"]["path"]
                yield item

(2)pipelines.py

  • 先导入scrapy框架中关于图片数据处理的专用模块
  • from scrapy.pipelines.images import ImagesPipeline
  • 第一个默认类不用管它,让他返回item数据,交给专有的图片类处理
    class DuitangPipeline:
        def process_item(self, item, spider):
            return item
  • 函数get_media_requests()的作用是将item中获取到的图片链接发起请求,并将获取到的数据转交给file_path函数处理。
    class ImagePipeline(ImagesPipeline):
        def get_media_requests(self, item, info):
            yield scrapy.Request(item["href"])
  • file_path函数 的作用是处理图片的命名方式,这里将图片链接中"/"符号后的后缀作为图片名进行保存,再将命名的名称返回。
        def file_path(self, request, response=None, info=None, *, item=None):
            img_name=request.url.split("/")[-1]
            return img_name
  • item_completed函数是将item在ImagePipeline管道进行返回。(若不返回则其他管道则无法获取到item数据,也就无法进行数据库等数据保存方式)
        def item_completed(self, results, item, info):
            print(item)
            return item
  • pipelines.py代码完整代码如下:
    import scrapy
    from itemadapter import ItemAdapter
    from scrapy.pipelines.images import ImagesPipeline
    
    class DuitangPipeline:
        def process_item(self, item, spider):
            return item
    
    class ImagePipeline(ImagesPipeline):
        def get_media_requests(self, item, info):
            yield scrapy.Request(item["href"])
    
        def file_path(self, request, response=None, info=None, *, item=None):
            img_name=request.url.split("/")[-1]
            return img_name
    
        def item_completed(self, results, item, info):
            print(item)
            return item
  • 由于之前已经在setting中设置好的图片保存路径,所以这里直接运行scrapy框架即可。

  • 到这里,我们运用scrapy框架进行图片爬取就完成了。

posted on 2023-02-26 22:21  乐之之  阅读(140)  评论(0编辑  收藏  举报