python_爬虫_scrapy_爬取360图片实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_39532362/article/details/88197638

创建项目

scrapy start project images360 #生成项目文件
scrapy genspider images images.so.com #创建一个新的spider,命名images,url为images.so.com

全局设置

settings.py里去掉注解及加入代码

# 忽略协议
ROBOTSTXT_OBEY = False

# 设置爬取得最大页数
max_page=50

# 开启管道,数值越少越优先处理
ITEM_PIPELINES = {
   'image360.pipelines.Image360Pipeline': 300,
   'image360.pipelines.Image360Pipeline_MySql': 400}

# 定义用于连接数据库的参数
MYSQL_HOST='localhost'
MYSQL_DATABASE='scrapy_test'
MYSQL_USER='root'
MYSQL_PASSWORD='123456'
MYSQL_PORT=3306

设置Item

items.py里编写item类

import scrapy

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

编写spider

images.py里编写spider

# -*- coding: utf-8 -*-
import scrapy
import urllib
import json
from image360.items import Image360Item

class ImagesSpider(scrapy.Spider):
  name = 'images'
  allowed_domains = ['images.so.com']
  start_urls = ['http://images.so.com/']

  # 重写start_requests生成30个请求,相当于start_urls设置30个链接
  def start_requests(self):
    # 解析网址,并设置其他不变的请求参数
    def urldecode(word):
      kvs=[kv for kv in word.split('&')]
      data=dict([tuple(kv.split('=')) for kv in kvs])
      return data
    word=r'ch=beauty&t1=595&src=banner_beauty&gid=964b6885fd605285a991a16988403f68&sn=60&listtype=new&temp=1'
    
    data=urldecode(word)
    base_url='http://image.so.com/zj?'
    for page in range(1,self.settings.get('MAX_PAGE')+1):
      data['sn']=page*30
      params=urllib.parse.urlencode(data)
      url=base_url+params
      yield scrapy.Request(url,self.parse)
       
  # 解析爬取结果
  def parse(self, response):
    result=json.loads(response.text)
    for image in result.get('list')[:10]:
      print('====>spider.parse')
      item=Image360Item()
      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

设置pipeline

直接设置

简单item处理

import requests
from scrapy.exceptions import DropItem

# 基本item处理
class Image360Pipeline(object):
  # 对图片链接数据实现保存
  def process_item(self,item,spider):
    response=requests.get(item['url'])
    with open('./images/%s'%item['url'].split('/')[-1],'wb') as f:
      f.write(response.content)

写入数据库

# 写进mysql
import pymysql
from scrapy.exceptions import DropItem

class Image360Pipeline_MySql(object):
  def __init__(self,host,database,user,password,port):
    self.host=host
    self.database=database
    self.user=user
    self.password=password
    self.port=port

  # 用setting变量初始化自身对象
  @classmethod
  def from_crawler(cls,crawler):
    return cls(
      host=crawler.settings.get('MYSQL_HOST'),
      database=crawler.settings.get('MYSQL_DATABASE'),
      user=crawler.settings.get('MYSQL_USER'),
      password=crawler.settings.get('MYSQL_PASSWORD'),
      port=crawler.settings.get('MYSQL_PORT'),
      )

  # spider开启时调用链接数据库
  def open_spider(self,spider):
    self.db=pymysql.connect(host=self.host,database=self.database,user=self.user,password=self.password,port=self.port,charset='utf8')
    self.cursor=self.db.cursor()

  # spider关闭时调用断开数据库
  def close_spider(self,spider):
    self.db.close()

  # 处理item,把item写入数据库并返回item
  def process_item(self,item,spider):
    data=dict(item)
    keys=','.join(data.keys())
    values=','.join(['%s']*len(data))
    # 这里需要事在数据库中创建表
    sql='insert into %s (%s) values (%s)'%('images',keys,values)
    self.cursor.execute(sql,tuple(data.values()))
    self.db.commit()
    return item

相关解析

  • process_item(self,item,spider)
    【item处理的主要内容在这里设置,必须返回item待可能继续的处理】
    item:就是被spider返回的item
    spider
  • from_crawler(cls,crawler)
    【用于初始化自身的函数,cls就是调用自身的__init__】
  • open_spider(self,spider)
    【spider启动时执行调用】
  • close_spider(self,spider)
    【spider关闭时时执行调用】

ImagesPipeline继承类设置

全局设置

settings.py去掉注解及加入代码

# 定义存储文件路径
`IMAGES_STORE='./images'`

编写代码

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

class Image360Pipeline(ImagesPipeline):
  # 处理item并返回新的请求
  def get_media_requests(self,item,info):
    yield scrapy.Request(item['url']) #可以指定callback函数
  # 根据对应的下载请求设置文件名
  def file_path(self,request,response=None,info=None):
    return request.url.split('/')[-1]
  # 根据对应的下载结果判断是否成功
  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

相关解析

  • class scrapy.pipelines.images.ImagesPipeline
    【一个高效率下载及保存图片的类,编写一个新的pipeline继承此类】
  • get_media_requests(item,info)
    【接收item,可根据其生成Request对象,返回的Request加入调度,等待执行下载】
  • file_path(request,response,info)
    【用于设置保存的文件名或路径】
    request:对应当前下载的Request对象
    response:本例需要设置为None
    info:本例需要设置为None
  • item_completed(self,results,item,info)
    【待新的下载完成后,处理对应的item对象】
    results:对应item的下载结果,列表形式,元素为元祖,包含成功标识信息及链接信息

猜你喜欢

转载自blog.csdn.net/weixin_39532362/article/details/88197638