Scrapy的日誌等級和請求傳參

嗚咽的時光喵發表於2019-01-15

日誌等級

日誌資訊:   使用命令: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

 

相關文章