Scrapy入门笔记(测试download图片)

环境搭建:

关于这一点,在Windows环境下,请务必使用 Anaconda 这个Python的发行版本,不然光环境的各种报错就能消磨掉你所有的学习兴趣!

参考文档:http://blog.csdn.net/u014175572/article/details/54427525

 

下面通过download图片的实例来展示Scrapy的基本功能。

 

使用Scrapy第一步:创建项目;CMD进入你需要放置项目的目录  输入:

 scrapy startproject XXXXX             XXXXX代表你项目的名字

例如我在工作路径下输入:

scrapy startproject mmjpg

创建成功就会显示:

New Scrapy project 'mmjpg', using template directory 'D:\\Anaconda3\\lib\\site-packages\\scrapy\\templates\\project', created in:
E:\pythonworkspace\mmjpg

You can start your first spider with:
cd mmjpg
scrapy genspider example example.com

用PyCharm工具打开,显示的目录结构如下:

一个小技巧,Scrapy默认是不能在IDE中调试的,我们在根目录中新建一个py文件叫:entrypoint.py;在里面写入以下内容:

from scrapy.cmdline import execute
execute(['scrapy', 'crawl', 'mmjpg'])

注意!第二行中代码中的前两个参数是不变的,第三个参数请使用自己的spider的名字。稍后我会讲到!!

 

建立一个项目之后:

第一件事情是在items.py文件中定义一些字段,这些字段用来临时存储你需要保存的数据。方便后面保存数据到其他地方,比如数据库 或者 本地文本之类的。

第二件事情在spiders文件夹中编写自己的爬虫

第三件事情在pipelines.py中存储自己的数据

还有一件事情,不是非做不可的,就settings.py文件 并不是一定要编辑的,只有有需要的时候才会编辑。

 

第一步定义字段:

在items.py这个文件中

就像下面这样:

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class MmjpgItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    # 图片集合名称
    title = scrapy.Field()
    # 图片序号
    picIndex = scrapy.Field()
    # 图片路径
    src_info = scrapy.Field()
    # 文件夹路径
    dirPath = scrapy.Field()

第二步编写Spider:

在spiders文件中新建一个mmjpg.py文件,结构如下:

具体的网页节点分析,提取省略,最终的代码如下:

# coding:utf-8
import time
import os
import re
import shutil
import scrapy  # 导入scrapy包
from bs4 import BeautifulSoup
from scrapy.http import Request  ##一个单独的request的模块,需要跟进URL的时候,需要用它
from mmjpg.items import MmjpgItem


class Myspider(scrapy.Spider):
    name = 'mmjpg'
    # allowed_domains = ['23wx.com']
    bash_url = 'http://www.mmjpg.com/'
    # bashurl = '.html'
    dir_path = 'G:\mmjpg'  # 图片存放的路径

    def start_requests(self):
        yield Request(self.bash_url, self.parse)

    #   1、获取总页数,并且遍历每一张列表页面页。
    def parse(self, response):
        # print(response.text)
        Soup = BeautifulSoup(response.text, 'lxml')
        page_div = Soup.find('div', class_='page').find('a',class_='last');
        # print(page_div);
        all_page_info = page_div['href'];
        # 获取到总页数
        all_page_number = all_page_info.split('/')[2];
        second_url = all_page_info.split('/')[1];
        for x in range(1, int(all_page_number) + 1):
            # http://www.mmjpg.com/home/2
            if x == 1:
                list_page = self.bash_url
            else:
                list_page = self.bash_url + second_url + '/' + str(x)
            # print(list_page)
            # self.getListInfo(list_page)
            yield Request(list_page, self.getListInfo)
            # print('遍历每一张列表页面页,休息2秒钟再继续......')
            # print('*' * 60)
            # time.sleep(2)

    # 2、获取每一张列表页面页里面的列表信息(标题+url)。
    def getListInfo(self, response):
        # print(response.url)
        list_info_html = response.text
        list_info_soup = BeautifulSoup(list_info_html, 'lxml')
        list_dd = list_info_soup.find('div', class_='pic').find_all('span', class_='title');
        for a in list_dd:
            # print(a['href'])
            item = a.find('a')
            title = item.get_text()  # 取出a标签的文本
            href = item['href']  # 取出a标签的href 属性
            # print(title, href)
            os.chdir(self.dir_path)

            # if self.mkdir(title):
            self.mkdir(title)
            # os.chdir(self.dir_path + '\\' + title)
            # print('进入[', title, ']文件夹......')
            # self.getContentInfo(href, title)
            yield Request(href, self.getContentInfo, meta={'dirPath': self.dir_path + '\\' + title})
        # time.sleep(2)
        # self.getContentInfo(href, title)

    # 3、获取每一个具体人物图片信息
    def getContentInfo(self, response):
        # os.chdir(self.dir_path + '\\' + title)
        # print('进入[', title, ']文件夹......休息2秒钟......')
        # time.sleep(2)
        dirPath = response.meta['dirPath']
        content_info_html = response.text
        content_info_soup = BeautifulSoup(content_info_html, 'lxml')
        page_dd = content_info_soup.find('div', class_='page').find_all('a')[-2]
        # print(page_dd.get_text().split('共')[1].split('页')[0])
        # 获取总的图片页数
        all_pic_page = page_dd.get_text();
        print('共有图片【', all_pic_page, '】张。')
        # print(all_pic_page)
        # 拼接详情url
        #   http://www.mmjpg.com/mm/854/42
        pic_url_fragment = response.url
        # print(pic_url_fragment)
        for x in range(1, int(all_pic_page) + 1):
            # print('-----',x);
            if x == 1:
                pic_url_info = response.url
            else:
                pic_url_info = pic_url_fragment + '/' + str(x)
            # print(pic_url_info)

            # self.getImgSrc(pic_url_info, x)
            yield Request(pic_url_info, self.getImgSrc, meta={'index': x, 'dirPath': dirPath})

    # 4、获取图片的src路径
    def getImgSrc(self, response):
        index = response.meta['index']
        dirPath = response.meta['dirPath']
        # print(response.url)
        img_src_html = response.text
        img_src_soup = BeautifulSoup(img_src_html, 'lxml')
        # print(img_src_soup)
        # exit()
        img_label = img_src_soup.find('div', class_='content').find('img')
        src_info = img_label.get('src')
        # http://img.mmjpg.com/2015/159/3.jpg
        name = str(index) + '.' + src_info.split('.')[-1]
        # print(name)
        mmjpgItem = MmjpgItem()
        mmjpgItem['picIndex'] = name
        mmjpgItem['src_info'] = src_info
        mmjpgItem['dirPath'] = dirPath
        return mmjpgItem

        # print(src_info)
        # self.saveImg(name, src_info)
        # print(time.strftime("%Y-%m-%d %H:%M:%S"))
        # print('下载了一张图片[', index, '.jpg],休息0.01秒再继续。')
        # time.sleep(0.01)

# ====================================================================================================#

    #   创建文件夹函数
    def mkdir(self, path):
        path = path.strip()
        # temp_path = str(path.encode('utf-8')).strip()
        # print path
        # path = unicode(path, "utf-8")
        # os.mkdir(os.path.join('E:\pythonworkspace\meizi', path))
        # os.chdir('E:\pythonworkspace\meizi\\' + path)
        isExists = os.path.exists(os.path.join(self.dir_path, path))
        if not isExists:
            os.makedirs(os.path.join(self.dir_path, path))
            print('建了一个名字叫做', path, '的文件夹!')
            # time.sleep(2)
            return True
        else:
            print('名字叫做[', path, ']的文件夹已经存在了!')
            return False

 第三件事情在pipelines.py中存储自己的数据

创建一个叫processdata的文件夹,在此文件夹下添加两个python文件,__init__.py和pipelines.py

其中__init__.py文件内容为空,pipelines.py的内容如下(此文件用于保存图片):

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
# from vvjob.vvjob_items import Vvjob_Item  ##这是我定义的需要保存的字段,(导入dingdian项目中,items文件中的DingdianItem类)
import time
import traceback

import requests  ##导入requests
import os


class PmmjpgPipeline(object):
    def process_item(self, item, spider):
        name = item['picIndex']
        img_url = item['src_info']
        dirPath = item['dirPath']
        print(name, '########', img_url, '#######', dirPath)
        # self.saveImg(name, img_url)

        os.chdir(dirPath)
        print('进入[', dirPath, ']文件夹......')
        self.saveImg(name, img_url)
        # with open(dirPath, 'wb') as handle:
        #     response = requests.get(img_url, stream=True)
        #     for block in response.iter_content(1024):
        #         if not block:
        #             break
        #
        #         handle.write(block)


        print(time.strftime("%Y-%m-%d %H:%M:%S"))
        print('下载了一张图片[', name, '.jpg]')
        return item

    ##这个函数保存图片
    def saveImg(self, name, img_url):
        img = self.requestImg(img_url)
        f = open(name, 'ab')
        f.write(img.content)
        f.close()

    def requestImg(self, url):  ##这个函数获取网页的response 然后返回
        try:
            img = requests.get(url, headers={
                                    'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"
                                })
        except Exception as e:
            traceback.print_exc()
            return self.requestImg(url)
        return img;

下面我们启用这个Pipeline在settings中作如下设置:

找到settings.py文件,如下图:

在此文件中找到ITEM_PIPELINES属性,打开这个注释。添加一行代码:

'mmjpg.processdata.pipelines.PmmjpgPipeline': 1,

截图如下:

PS: mmjpg(项目目录).processdata(自己建立的processdata文件夹目录).pipelines(自己建立的pipelines文件).PmmjpgPipeline(其中定义的类) 后面的 1 是优先级程度(1-1000随意设置,数值越低,组件的优先级越高)

好!我们来运行一下试试!!Go Go Go!

首先在G盘下创建一个文件夹mmjpg用来保存图片。这个路径在mmjpg.py代码中已经定义好。

打开entrypoint.py文件,按Ctrl+Shift+F10运行

此时在自定义的文件夹下图片已经在下载中:

posted @ 2017-04-17 17:09  天南韩立  阅读(207)  评论(0编辑  收藏  举报