欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Scrapy的日志等级和请求传参

程序员文章站 2023-01-14 20:29:25
日志等级 日志信息: 使用命令:scrapy crawl 爬虫文件 运行程序时,在终端输出的就是日志信息; 日志信息的种类: ERROR:一般错误; WARNING:警告; INFO:一般的信息; DEBUG: 调试信息; 设置日志信息指定输出: 在settings配置文件中添加: LOG_LEVE ......

日志等级

日志信息:   使用命令:scrapy crawl 爬虫文件 运行程序时,在终端输出的就是日志信息;

日志信息的种类:

  •   error:一般错误;
  •   warning:警告;
  •   info:一般的信息;
  •   debug: 调试信息;

设置日志信息指定输出:

  在settings配置文件中添加:

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

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

请求传参

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

通过 在scrapy.request()中添加 meta参数 进行传参;

scrapy.request()

案例展示爬取www.55xia.com电影网,将一级页面中的电影名称,类型,评分一级二级页面中的上映时间,导演,片长进行爬取。

爬虫程序

# -*- coding: utf-8 -*-
import scrapy
from moviepro.items import movieproitem

class moviespider(scrapy.spider):
    name = 'movie'
    allowed_domains = ['www.55xia.com']
    start_urls = ['http://www.55xia.com/']

    def parse(self, response):
        div_list = response.xpath('//div[@class="col-xs-1-5 movie-item"]')

        for div in div_list:
            item = movieproitem()
            item['name'] = div.xpath('.//h1/a/text()').extract_first()
            item['score'] = div.xpath('.//h1/em/text()').extract_first()

            #xpath(string(.))表示提取当前节点下所有子节点中的数据值(.)表示当前节点
            item['kind'] = div.xpath('.//div[@class="otherinfo"]').xpath('string(.)').extract_first()
            item['detail_url'] = div.xpath('./div/a/@href').extract_first()

            #请求二级详情页面,解析二级页面中的相应内容,通过meta参数进行request的数据传递
            yield scrapy.request(url=item['detail_url'],callback=self.parse_detail,meta={'item':item})

    def parse_detail(self,response):
        #通过response获取item
        item = response.meta['item']

        item['actor'] = response.xpath('//div[@class="row"]//table/tr[1]/a/text()').extract_first()
        item['time'] = response.xpath('//div[@class="row"]//table/tr[7]/td[2]/text()').extract_first()
        item['long'] = response.xpath('//div[@class="row"]//table/tr[8]/td[2]/text()').extract_first()

        #提交item到管道
        yield item

items

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

# define here the models for your scraped items
#
# see documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class movieproitem(scrapy.item):
    # define the fields for your item here like:
    name = scrapy.field()
    score = scrapy.field()
    time = scrapy.field()
    long = scrapy.field()
    actor = scrapy.field()
    kind = scrapy.field()
    detail_url = scrapy.field()

pipelines

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

# define your item pipelines here
#
# don't forget to add your pipeline to the item_pipelines setting
# see: https://doc.scrapy.org/en/latest/topics/item-pipeline.html

import json
class moviepropipeline(object):
    def __init__(self):
        self.fp = open('data.txt','w')
    def process_item(self, item, spider):
        dic = dict(item)
        print(dic)
        json.dump(dic,self.fp,ensure_ascii=false)
        return item
    def close_spider(self,spider):
        self.fp.close()

提高爬取效率

  爬取数据的过程中可能会遇到很多条数据,导致爬取效率变低,修改settings文件中的配置就能提高爬取效率.

1.增加并发量:

  默认最大的并发量为32,可以通过设置settings文件修改

concurrent_requests = 100

  将并发改为100

2.降低日志等级:

  在运行scrapy时,会有大量日志信息的输出,为了减少cpu的使用率。可以设置log输出信息为info或者error即可。修改settings.py

log_level = 'info'

3.禁止cookie:

  如果不是真的需要cookie,则在scrapy爬取数据时可以进制cookie从而减少cpu的使用率,提升爬取效率。修改settings.py

cookies_enabled = false

4.禁止重试:

  对失败的http进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。修改settings.py

retry_enabled = false

5.减少下载超时:

  如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。修改settings.py

download_timeout = 10 

小试牛刀

 

爬取4k高清壁纸网站的图片并且提高爬取效率

爬虫程序

# -*- coding: utf-8 -*-
import scrapy
from ..items import picproitem


class picspider(scrapy.spider):
    name = 'pic'
    # allowed_domains = ['www.pic.com']
    start_urls = ['http://pic.netbian.com/']

    def parse(self, response):
        li_list = response.xpath('//div[@class="slist"]/ul/li')
        print(li_list)
        for li in li_list:
            img_url ="http://pic.netbian.com/"+li.xpath('./a/span/img/@src').extract_first()
            # print(66,img_url)
            title = li.xpath('./a/span/img/@alt').extract_first()
            print("title:", title)
            item = picproitem()
            item["name"] = title

            yield scrapy.request(url=img_url, callback =self.getimgdata,meta={"item":item})


    def getimgdata(self, response):
        item = response.meta['item']
        # 取二进制数据在body中
        item['img_data'] = response.body

        yield item

pipelines

import os
class picpropipeline(object):
    def open_spider(self,spider):
        if not os.path.exists('piclib'):
            os.mkdir('./piclib')
    def process_item(self, item, spider):
        imgpath = './piclib/'+item['name']+".jpg"
        with open(imgpath,'wb') as fp:
            fp.write(item['img_data'])
            print(imgpath+'下载成功!')
        return item

settings

user_agent = 'mozilla/5.0 (windows nt 6.1; wow64) applewebkit/537.36 (khtml, like gecko) chrome/70.0.3538.102 safari/537.36'


# obey robots.txt rules
robotstxt_obey = false

item_pipelines = {
   'picpro.pipelines.picpropipeline': 300,
}


# 打印具体错误信息
log_level ="error"

#提升爬取效率

concurrent_requests = 10
cookies_enabled = false
retry_enabled = false
download_timeout = 5