美文网首页
2020-07-19--scrapy框架2

2020-07-19--scrapy框架2

作者: program_white | 来源:发表于2020-07-20 21:43 被阅读0次

scrapy调试

通常,运行scrapy爬虫的方式是在命令行输入scrapy crawl ,调试的常用方式是在命令行输入scrapy shell 。总的来说,调试方法比较单一。
其实,还有两种调试方法,可以在pycharm中实现调试。

1.使用scrapy.cmdline的execute方法 首先,在项目文件scrapy.cfg的同级建立main.py文件(注意,必须是同级建立),在其中键入如下代码:

from scrapy.cmdline import execute

execute('scrapy crawl blog'.split())
# 或
# execute(['scrapy', 'crawl', 'spider_name'])   spider_name替换为你自己的爬虫名称

Spiders

Spider类定义了如何爬取某个网站。包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item)。简而言之,Spider就是你定义爬取的动作及分析某个网页(或者是有些网页)的地方。

对spider来说,爬取的循环类似如下:

以初始的URL初始化Request,并设置回调函数。当该request下载完毕并返回时,将生成response,并作为参数传给该回调函数。spider中初始的request是通过调用start_requests() 来获取。start_requests() 读取start_urls中的URL,并以parse为回调函数生成 Request。

在回调函数内分析返回的(网页)内容,返回 Item 对象、dict、 Request 或者一个包括三者的可迭代容器。 返回的Request对象之后会经过Scrapy处理,下载相应的内容,并调用设置的callback函数(函数可相同)。

在回调函数内,您可以使用 选择器(Selectors) (您也可以使用BeautifulSoup, lxml 或者您想用的任何解析器) 来分析网页内容,并根据分析的数据生成item。

最后,由spider返回的item将被存到数据库(由某些 Item Pipeline 处理)

Scrapy爬取博客园精华区内容

之前我们都是爬取了一个页面,这次爬取多个页面

编写items.py文件 定义需要爬取的内容。

class CnblogsItem(scrapy.Item):
    # define the fields for your item here like:
    post_author = scrapy.Field()    #发布作者
    author_link = scrapy.Field()    #作者博客主页链接
    post_date = scrapy.Field()      #发布时间
    digg_num = scrapy.Field()       #推荐数
    title = scrapy.Field()          #标题
    title_link = scrapy.Field()     #标题链接
    item_summary = scrapy.Field()   #摘要
    comment_num = scrapy.Field()    #评论数
    view_num = scrapy.Field()       #阅读数

在spiders/blog.py中编写爬虫:

    def parse(self, response:HtmlResponse):
        # BlogItem
        # 获取文章对象列表
        blist = response.xpath('//div[@id="post_list"]/div[@class="post_item"]')
        print(blist)

        for it in blist:
            blog = CnblogsItem()

            #作者
            auth = it.xpath('.//div[@class="post_item_body"]/div[1]/a/text()').extract_first()
            #作者blog主页连接
            auth_url = it.xpath('.//div[@class="post_item_body"]/div[1]/a/@href').extract_first()
            #发布时间
            time = it.xpath('.//div[@class="post_item_body"]/div[1]/text()').extract()
            # 推荐数
            digg_num = it.xpath('./div[1]/div[1]/span/text()').extract_first()
            # 标题
            title = it.xpath('.//div[@class="post_item_body"]//h3/a/text()').extract_first()
            # 标题链接
            title_link = it.xpath('.//div[@class="post_item_body"]//h3/a/@href').extract_first()
            # 摘要
            item_summary = it.xpath('.//div[@class="post_item_body"]/p/text()').extract_first()
            # 评论数
            comment_num = it.xpath('.//div[@class="post_item_body"]/div[1]/span[1]/a/text()').extract_first()
            # 阅读数
            view_num = it.xpath('.//div[@class="post_item_body"]/div[1]/span[2]/a/text()').extract_first()

            print(auth,auth_url,time,digg_num,title,title_link,item_summary,comment_num,view_num)
            blog['post_author'] = auth
            blog['author_link'] = auth_url
            blog['post_date'] = time
            blog['digg_num'] = digg_num
            blog['title'] = title
            blog['title_link'] = title_link
            blog['item_summary'] = item_summary
            blog['comment_num'] = comment_num
            blog['view_num'] = view_num
            yield blog

        #获取下一页链接
        #a[text()="Next >"]:获取文本内容为Next >的a标签
        next = response.xpath('//a[text()="Next >"]/@href').extract_first()
        # print(next)
        if next:
            next_url = f'http://www.cnblogs.com{next}'
            yield scrapy.Request(
                next_url,
                callback=self.parse
            )

分析:

  1. 首先获取第一个url,进入parse函数,传进来的response是当前页的响应。
  2. 根据xpath语法获取每个列表项的对象,返回一个列表blist。
  3. 遍历该列表,分别获取每一项的元素对象it,在it的基础上再进行解析,分别获取作者,作者链接,发布时间。推荐数,标题,标题链接,摘要,评论数,阅读数的对象,使用extract()/extract_first()转为单个对象/列表。

4.创建item数据包,将这些数据加入item数据对象中,yield发送给引擎-->管道文件。
到此第一页的数据爬取完成。
5.利用response解析到Next按钮的链接(也就是下一页的url)
6.判断该url是否存在,如果存在,yield给调度器一个scrapy下的Request()对象,该对象传递两个值,下一个url和回调函数名,进行下一次的爬取。

当管道文件下有多个类时需要判断类型item与需要获取的类型是否一致。

CrawlSpider

class scrapy.spiders.CrawlSpider 在爬取一些特殊类型的网站时,比如一些博客类网站,其网页的链接都会有一些特殊的形式

http://www.cnblogs.com/book/7357421.html
http://www.cnblogs.com/book/7356835.html

比如我们想爬取博客链接,会发现,除了最后的几个数字不同,其他的内容是相同的,因此,我们就可以通过这个类来进行自动抓取相似的链接,而无需我们自己定义。

CrawlSpider类定义了如下的属性和方法:

  • rules 一个包含一个(或多个) Rule 对象的集合(list)。 每个 Rule 对爬取网站的动作定义了特定表现。 Rule对象在下边会介绍。 如果多个rule匹配了相同的链接,则根据他们在本属性中被定义的顺序,第一个会被使用。

  • CrawlSpider需要配合scrapy.spiders.Rule类来实现定义规则 下面介绍scrapy.spiders.Rule类 class scrapy.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None)

  • link_extractor 这是一个 Link Extractor 对象。 其定义了如何从爬取到的页面提取链接。

  • callback 这是一个callable或string(该spider中同名的函数将会被调用)。 从link_extractor中每获取到链接时将会调用该函数。该回调函数接受一个response作为其第一个参数, 并返回一个包含 Item 以及(或) Request 对象(或者这两者的子类)的列表(list) cb_kwargs 包含传递给回调函数的参数(keyword argument)的字典。 follow 是一个布尔(boolean)值,指定了根据该规则从response提取的链接是否需要跟进。 如果 callback 为None, follow 默认设置为 True ,否则默认为 False 。 process_links 是一个callable或string(该spider中同名的函数将会被调用)。 从link_extractor中获取到链接列表时将会调用该函数。该方法主要用来过滤。 process_request 是一个callable或string(该spider中同名的函数将会被调用)。 该规则提取到每个request时都会调用该函数。该函数必须返回一个request或者None。 (用来过滤request)

CrawlSpider爬取读书网

爬取网页https://www.dushu.com/book/1163_2.html


上边的2就是页数。

一、开始一个读书网项目

scrapy startproject 项目名称
cd 项目名称/项目名称/spiders
scrapy genspider -t crawl 爬虫名称 域名

scrapy startproject dushu      #创建dushu项目
cd dushu/dushu/spiders       #进入项目下的spiders目录下
scrapy genspider -t crawl ds www.dushu.com         #创建CrawlSpider爬虫文件

使用pycharm打开项目,项目结构与上一章结构一致,但是文件中内容不同。

二、链接提取规则


class DsSpider(CrawlSpider):
    name = 'ds'
    allowed_domains = ['www.dushu.com']
    start_urls = ['https://www.dushu.com/book/1163_1.html']
    rules = (
        Rule(LinkExtractor(allow=r'/book/1163_\d+.html'), callback='parse_item', follow=True),
    )

起始url为https://www.dushu.com/book/1163_1.html,当运行爬取时,会自动匹配规则中allow的正则表达式,不断地匹配第二页,第三页的url,并且回调parse_item(),实现多页爬取。

修改parse_item方法用于解析数据:

    def parse_item(self, response:HtmlResponse):
        # 获取每个书的元素,返回元素对象列表
        blist = response.xpath('//div[@class="bookslist"]/ul/li')
        # print(blist)
        for it in blist:
            book = DushuItem()
            # 从当前it元素位置出发查询下属图片
            img = it.xpath('./div/div/a/img[1]')
            # 获取书名
            title = img.xpath('./@alt').extract_first()
            # 获取书的链接
            src = img.xpath('./@data-original').extract_first()
            # 获取书的作者
            auth = it.xpath('./div/p[1]/text()').extract_first()
            # print(title,src,auth)
            book['title'] = title
            book['src'] = src
            book['auth'] = auth

            yield book

四、修改pipelines.py文件用于写入数据

class DushuPipeline:
    def open_spider(self, spider):
        self.fp = open('dushu.json', 'wb')
        self.exporter = JsonLinesItemExporter(self.fp, ensure_ascii=False, encoding='utf-8')
        self.fp.write(b"[")
    def process_item(self, item, spider):

        # self.fp.write(str(item)+"\n")
        self.exporter.export_item(item)
        self.fp.write(b",")
        return item

    def close_spider(self, spider):
        self.fp.write(b"]")
        self.fp.close()

items.py

import scrapy

class DushuItem(scrapy.Item):

    # define the fields for your item here like:
    src = scrapy.Field()  # 发布作者
    alt = scrapy.Field()  # 作者博客主页链接
    author = scrapy.Field()  # 发布时间

记得将settings.py中的管道和用户代理和守则修改了。
运行即可。

相关文章

  • 2020-07-19--scrapy框架2

    scrapy调试 通常,运行scrapy爬虫的方式是在命令行输入scrapy crawl ,调试的常用方式是在命令...

  • 2020-07-19--scrapy框架1

    概览 在具体的学习scrapy之前,我们先对scrapy的架构做一个简单的了解,之后所有的内容都是基于此架构实现的...

  • Android 常用

    常用 文1 1.# android通用流行框架2.# android优秀框架整理2.# android优秀框架整理2

  • 框架2

    1、任何事情都是一个框架,先要启动框架,然后再执行,做事情前先想框架,其实就是先找模型。 2、一定做什么要先找路,...

  • iOS-基本技术总结

    1、基本框架:Foundation框架、UIKit框架 2、高级框架:Core Data 、Core Graphi...

  • EAS-BOS 整体介绍

    1.BOS开发框架图1 2.BOS开发框架图2

  • Node.js--Express框架

    0. 框架安装 1.框架特性 2. 框架入门

  • 笔记之Struts2工作原理

    Struts2工作原理 struts2框架是SSH框架集中的框架之一,是一个基于MVC设计模式的Web应用框架,它...

  • Android Retrofit 2 + Retrofit 2

    实现MVC基础框架实现MVP基础框架(一)Android Retrofit 2 + Retrofit 2 封装(二...

  • 15_Spring SSH整合准备

    SSH框架 SSH = Struts2 + Spring + Hibernate Struts2框架整合所需jar...

网友评论

      本文标题:2020-07-19--scrapy框架2

      本文链接:https://www.haomeiwen.com/subject/zbydkktx.html