zoukankan      html  css  js  c++  java
  • scrapy框架post请求发送,五大核心组件,日志等级,请求传参

    一、post请求发送

    - 问题:爬虫文件的代码中,我们从来没有手动的对start_urls列表中存储的起始url进行过请求的发送,但是起始url的确是进行了请求的发送,那这是如何实现的呢?

    - 解答:其实是因为爬虫文件中的爬虫类继承到了Spider父类中的start_requests(self)这个方法,该方法就可以对start_urls列表中的url发起请求:

     def start_requests(self):
            for u in self.start_urls:
               yield scrapy.Request(url=u,callback=self.parse)

    【注意】该方法默认的实现,是对起始的url发起get请求,如果想发起post请求,则需要子类重写该方法。

    -方法: 重写start_requests方法,让其发起post请求:

    def start_requests(self):
            #请求的url
            post_url = 'http://fanyi.baidu.com/sug'
            # post请求参数
            formdata = {
                'kw': 'wolf',
            }
            # 发送post请求
            yield scrapy.FormRequest(url=post_url, formdata=formdata, callback=self.parse)

    在scrapy框架中默认情况下cookie会被自动处理,无需手动!

    二.五大核心组件工作流程

      • 引擎(Scrapy)
        用来处理整个系统的数据流处理, 触发事务(框架核心)
      • 调度器(Scheduler)
        用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
      • 下载器(Downloader)
        用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)
      • 爬虫(Spiders)
        爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面
      • 项目管道(Pipeline)
        负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。

    三、scrapy日志等级

    在使用scrapy crawl spiderFileName运行程序时,在终端里打印输出的就是scrapy的日志信息。

      - 日志信息的种类:

            ERROR : 一般错误

            WARNING : 警告

            INFO : 一般的信息

            DEBUG : 调试信息

           

      - 设置日志信息指定输出:

        在settings.py配置文件中,加入

                        LOG_LEVEL = ‘指定日志信息种类’ 即可。

           LOG_LEVEL = 'ERROR' 只打印错误日志。

                        LOG_FILE = 'log.txt'  则表示将日志信息写入到指定文件中进行存储。

    四、请求传参

     在某些情况下,我们爬取的数据不在同一个页面中,例如,我们爬取一个电影网站,电影的名称,评分在一级页面,而要爬取的其他电影详情在其二级子页面中。这时我们就需要用到请求传参。

      - 案例:爬取boos直聘上的招聘信息,将一级页面中的工作名称,薪资,公司, 二级页面中的工作详情进行爬取。

    爬虫文件:

    import scrapy
    from ..items import BoosproItem
    
    # 当我们请求的数据不在同一页面中,那么必须使用请求传参
    class BoosSpider(scrapy.Spider):
        name = 'boos'
        # allowed_domains = ['www.xxx.com']
        start_urls = ['https://www.zhipin.com/c101010100/?query=python%E7%88%AC%E8%99%AB&page=1']
    
        # 通用的url模板
        url = 'https://www.zhipin.com/c101010100/?query=python%E7%88%AC%E8%99%AB&page={}'
        pageNum = 1
    
        def parse(self, response):
            li_list = response.xpath('//div[@class="job-list"]/ul/li')
            for li in li_list:
                item = BoosproItem()
    
                job_name = li.xpath('.//div[@class="job-title"]/text()').extract_first()
                salary = li.xpath('.//div[@class="info-primary"]/h3/a/span/text()').extract_first()
                company = li.xpath('.//div[@class="company-text"]/h3/a/text()').extract_first()
                # url拼接
                detail_url = 'https://www.zhipin.com' + li.xpath('.//div[@class="info-primary"]/h3/a/@href').extract_first()
    
                # 将解析到的数据存储到item类型的对象中
                item['job_name'] = job_name
                item['salary'] = salary
                item['company'] = company
    
                # 对详情页的url进行手动请求的发送 , callback请求成功后的回调函数,
                # 请求传参,将meta所对应的值传递给回调函数
                yield scrapy.Request(url=detail_url, callback=self.parsrDetail, meta={'item': item})
    
            # 对其他的页码进行手动请求
            if self.pageNum <= 3:
                self.pageNum += 1
                newUrl = self.url.format(self.pageNum)
                yield scrapy.Request(url=newUrl, callback=self.parse)
    
        # 用来解析详情页的相关的数据
        def parsrDetail(self,response):
            # 接收meta
            item = response.meta['item']
            job_desc = response.xpath('//*[@id="main"]/div[3]/div/div[2]/div[2]/div[1]/div//text()').extract()
            job_desc = ''.join(job_desc)
            # 将job_desc封装到item中
            item['job_desc'] = job_desc
    
            # 提交item 到管道
            yield item

    items文件:

    import scrapy
    
    
    class BoosproItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        job_name = scrapy.Field()
        salary = scrapy.Field()
        company = scrapy.Field()
        job_desc = scrapy.Field()

    管道文件:

    class BoosproPipeline(object):
    
        # 该方法只会被执行一次,
        def open_spider(self, spider):
            self.fp = open('./boos.txt', 'w', encoding='utf-8')
    
        # 用于处理item的方法,爬虫文件每次提交一次item方法就会被调用一次
        def process_item(self, item, spider):
            # 取出item中的值
            job_name = item["job_name"].strip()
            salary = item["salary"].strip()
            company = item["company"].strip()
            job_desc = item["job_desc"].strip()
            self.fp.write(job_name + ":" + salary + "
    " + company + "
    " + job_desc + '
    
    ')
            return item  # 返回给了下一个即将被执行的管道类
    
        # 关闭文件夹
        def close_spider(self, spider):
            self.fp.close()

    注意settings中的配置:

    开启管道,

    robotstxt改为False,

    UA伪装,

    日志指定输出, LOG_LEVEL = 'ERROR'

    
    
  • 相关阅读:
    (5)Linux权限管理
    paloalto防火墙版本升级
    paloalto防火墙安装内容和软件更新
    paloalto防火墙激活许可证和订阅
    paloalto防火墙注册
    paloalto防火墙执行初始配置
    paloalto防火墙的优势
    方位话机X2主、备用服务器问题
    心态
    paloalto防火墙接口使用方法及实例
  • 原文地址:https://www.cnblogs.com/zwq-/p/10591207.html
Copyright © 2011-2022 走看看