前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python scrapy学习笔记(二)

python scrapy学习笔记(二)

作者头像
py3study
发布2020-01-08 16:02:10
4660
发布2020-01-08 16:02:10
举报
文章被收录于专栏:python3python3python3

使用scrapy批量抓取,参考http://python.jobbole.com/87155

一、创建项目

# scrapy startproject comics

创建完成后的目录结构

.
├── comics
│   ├── __init__.py
│   ├── items.py
│   ├── middlewares.py
│   ├── pipelines.py
│   ├── settings.py
│   └── spiders
│       └── __init__.py
└── scrapy.cfg

二、创建Spider类

start_requests:启动爬虫的时候调用,默认是调用make_requests_from_url方法爬取start_urls的链接,可以在这个方法里面定制,如果重写了该方法,start_urls默认将不会被使用,可以在这个方法里面定制一些自定义的url,如登录,从数据库读取url等,本方法返回Request对象

start_urls是框架中提供的属性,为一个包含目标网页url的数组,设置了start_urls的值后,不需要重载start_requests方法,爬虫也会依次爬取start_urls中的地址,并在请求完成后自动调用parse作为回调方法。

# cd comics/spiders
# vim comic.py

#!/usr/bin/python
#coding:utf-8

import scrapy

class Comics(scrapy.Spider):

    name = "comics"

    def start_requests(self):
        urls = ['http://www.xeall.com/shenshi']
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        self.log(response.body);

三、开始爬取漫画

爬虫的主要任务是爬取列表中每一部漫画的图片,爬取完当前页后,进入下一页漫画列表继续爬取漫画,依次不断循环直至所有漫画爬取完毕。思路:获取当前的漫画的URl,访问后获取漫画的名字和所有的图片的URL,进行批量下载,循环往复

1、获取当前页面中漫画的url,同时获取下一个

单个漫画的url

wKioL1hsnA7AMkTFAAAlDaAq7U4318.jpg
wKioL1hsnA7AMkTFAAAlDaAq7U4318.jpg
# 找出所有的漫画url                                                                                                                                                
def parse(self, response):
# 找出所有的漫画url
def parse(self, response):

    # 请求返回的response对象
    content = Selector(response=response)

    # 获取漫画标签对象
    com_count = content.xpath("//div[@class='mainleft']/ul/li")

    # 获取单页中所有漫画的url
    comics_url_list = []
    base_url = 'http://www.xeall.com'
    for i in range(len(com_count)):
        com_url = content.xpath("//div[@class='mainleft']/ul/li[{}]/a/@href".format(i+1)).extract()
        url = base_url+com_url[0]
        comics_url_list.append(url)

    # 处理当前页每部漫画
    for url in comics_url_list:
        yield scrapy.Request(url=url, callback=self.comics_parse)

    # 获取下一页的url
    url_num = content.xpath("//div[@class='mainleft']/div[@class='pages']/ul/li")
    next_url = content.xpath("//div[@class='mainleft']/div[@class='pages']/ul/li[{}]/a/@href".format(len(url_num)-3)).extract()

    # print '总页数: {},下一页: {}'.format(url_num,next_url)

    # 判断下一页是否为最后一页
    if next_url:
        next_page = 'http://www.xeall.com/shenshi/' + next_url[0]
        if next_page is not None:
            yield scrapy.Request(next_page, callback=self.parse)
            pass

2、获取所有页面

不同页面的源码

wKiom1hsnT2D-yNrAAAr1oadPro881.jpg
wKiom1hsnT2D-yNrAAAr1oadPro881.jpg

当前漫画的名字和url

wKiom1hsnbax886sAAA0_eZ3Pjo918.jpg
wKiom1hsnbax886sAAA0_eZ3Pjo918.jpg
# 提取每部漫画数据
def comics_parse(self, response):                                                                                                                                  

    content = Selector(response=response)

    # 当前页数
    page_num = content.xpath("//div[@class='dede_pages']/ul/li[@class='thisclass']/a/text()").extract()

    # 首张图片的url
    current_url = content.xpath("//div[@class='mhcon_left']/ul/li/p/img/@src").extract()

    # 漫画名称
    comic_name = content.xpath("//div[@class='mhcon_left']/ul/li/p/img/@alt").extract()

    # self.log('img url: ' + current_url[0])

    # 将图片保存到本地
    self.save_img(page_num[0], comic_name[0], current_url[0])

    # 下一页图片的url,当下一页标签的href属性为‘#’时为漫画的最后一页
    page_num = content.xpath("//div[@class='dede_pages']/ul/li")
    next_page = content.xpath("//div[@class='dede_pages']/ul/li[{}]/a/@href".format(len(page_num))).extract()

    # 最后一页中href='#' 
    if next_page == '#':
        print('parse comics:' + comic_name + 'finished.')
    else:
        next_page = 'http://www.xeall.com/shenshi/' + next_page[0]
        yield scrapy.Request(next_page, callback=self.comics_parse)

3、将数据持久化存储

# 将图片编号,图片名,图片url作为参数传入
def save_img(self, img_mun, title, img_url):                                                                                                                       
    # 将图片保存到本地
    # self.log('saving pic: ' + img_url)

    # 保存漫画的文件夹
    document = os.path.join(os.getcwd(),'cartoon')

    # 每部漫画的文件名以标题命名
    comics_path = os.path.join(document,title)
    exists = os.path.exists(comics_path)

    if not exists:
        print('create document: ' + title)
        os.makedirs(comics_path)

    # 每张图片以页数命名
    pic_name = comics_path + '/' + img_mun + '.jpg'

    # 检查图片是否已经下载到本地,若存在则不再重新下载
    exists = os.path.exists(pic_name)
    if exists:
        print('pic exists: ' + pic_name)
        return

    try:
        response = requests.get(img_url,timeout=30)

        # 请求返回到的数据
        data = response

        with open(pic_name,'wb') as f:
            for chunk in data.iter_content(chunk_size=1024):
                if chunk:
                    f.write(chunk)
                    f.flush()

        print('save p_w_picpath finished:' + pic_name)

    except Exception as e:
        print('save p_w_picpath error.')
        print(e)

完整源码地址 https://github.com/yaoliang83/Scrapy-for-Comics

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档