Python网络爬虫(scrapy的日志等级和请求传参)

一、Scrapy的日志等级

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

  日志信息的种类:

    ERROR : 一般错误

    WARNING : 警告

    INFO : 一般的信息

    DEBUG : 调试信息   

  设置日志信息指定输出:

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

LOG_LEVEL = ‘指定日志信息种类’即可。
LOG_FILE = 'log.txt'则表示将日志信息写入到指定文件中进行存储。

# 例如:
LOG_LEVEL = "ERROR"
LOG_FILE = 'log.txt'

二、如何提高scrapy的爬取效率(settings配置)

- 增加并发:

  默认scrapy开启的并发线程为32个,可以适当进行增加。在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100。

- 降低日志级别:

  在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。可以设置log输出信息为INFO或者ERROR即可。在配置文件中编写:LOG_LEVEL = ‘INFO’

- 禁止cookie:

  如果不是真的需要cookie,则在scrapy爬取数据时可以进制cookie从而减少CPU的使用率,提升爬取效率。在配置文件中编写:COOKIES_ENABLED = False

- 禁止重试:

  对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。在配置文件中编写:RETRY_ENABLED = False

- 减少下载超时:

  如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。在配置文件中进行编写:DOWNLOAD_TIMEOUT = 10 超时时间为10s

  配置文件,settings.py

配置文件:

USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False  # 不遵守爬虫文件协议

# Configure maximum concurrent requests performed by Scrapy (default: 16)
CONCURRENT_REQUESTS = 100  # 并发线程设置100个
COOKIES_ENABLED = False  # 不使用cookie
LOG_LEVEL = 'ERROR'  # 日志等级输出级别:错误(ERROR)级别才输出到终端
RETRY_ENABLED = False  # 网页数据请求失败则不重新请求
DOWNLOAD_TIMEOUT = 3  # 网络请求超时时间3秒
# Configure a delay for requests for the same website (default: 0)
# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
DOWNLOAD_DELAY = 3

三、scrapy手动请求发送与请求传参

  案例展示:爬取boos直聘,将boss直聘中的岗位信息,薪资及工作的具体内容进行爬取

  3.1 手动请求发送:

  在某些情况下,我们爬取内容存在多页数据时,需要自动指定爬取页数,通过递归调用parse函数对每页数据做数据解析

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

# 处理手动请求
class BoosSpider(scrapy.Spider):
    name = 'boos'
    # allowed_domains = ['www.xx.com']
    # 爬虫开始请求的url列表
    start_urls = [
        'https://www.zhipin.com/job_detail/?query=python开发&city=101010100&industry=&position=']


    # 数据解析
    def parse(self, response):
        li_list = response.xpath('//*[@id="main"]/div/div[3]/ul/li | //*[@id="main"]/div/div[2]/ul/li')
        for li in li_list:
            job_title = li.xpath('.//div[@class="info-primary"]/h3/a/div[1]/text()').extract_first()
            salary = li.xpath('.//div[@class="info-primary"]/h3/a/span/text()').extract_first()

            # 实例化item对象
            item = BoosproItem()
            item["job_title"] = job_title
            item["salary"] = salary
           
            # 提交item对象到管道
            yield item

        # 当添加不满足时,递归结束
        if self.page <= 5:
            self.page += 1
            print("正在爬去第{}页数据!".format(self.page))
            # 通过url模板拼接新的url
            new_url = format(self.base_url%self.page)
            # 手动请求发送 递归调用parse函数,对数据做解析
            yield scrapy.Request(new_url, callback=self.parse)

  3.1 请求传参:

  我们爬取内容职位工作具体内容在每个公司详情页里面,这时候就需要用到动态传参,把item对象传递到详情页的数据解析函数中

  参数传递:meta = {"item": item},通过meta关键字传递给callback函数

  参数接收:item = response.meta['key']

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


# 处理手动请求
# 请求参数处理
class BoosSpider(scrapy.Spider):
    name = 'boos'
    # allowed_domains = ['www.xx.com']
    # 爬虫开始请求的url列表
    start_urls = [
        'https://www.zhipin.com/job_detail/?query=python开发&city=101010100&industry=&position=']

    # 指定第二页page
    page = 2
    # 指定通用url模板
    base_url = "https://www.zhipin.com/c101010100/?query=python开发&page=%d"

    # 数据解析
    def parse(self, response):
        li_list = response.xpath('//*[@id="main"]/div/div[3]/ul/li | //*[@id="main"]/div/div[2]/ul/li')
        for li in li_list:
            job_title = li.xpath('.//div[@class="info-primary"]/h3/a/div[1]/text()').extract_first()
            salary = li.xpath('.//div[@class="info-primary"]/h3/a/span/text()').extract_first()
            detail_url = "https://www.zhipin.com"+li.xpath('.//div[@class="info-primary"]/h3/a/@href').extract_first()

            # 实例化item对象
            item = BoosproItem()
            item["job_title"] = job_title
            item["salary"] = salary

            # 职位详情页 请求参数处理(item对象传参)
            yield scrapy.Request(detail_url, callback=self.detail_parse, meta={"item": item})

        # 当添加不满足时,递归结束
        if self.page <= 5:
            self.page += 1
            print("正在爬去第{}页数据!".format(self.page))
            # 通过url模板拼接新的url
            new_url = format(self.base_url%self.page)
            # 递归调用parse函数,对数据做解析
            yield scrapy.Request(new_url, callback=self.parse)


    # 详情页数据解析 回调函数
    def detail_parse(self, response):
        # 获取到item对象
        item = response.meta["item"]

        # 职位描述信息 复数(extract)
        job_desc = response.xpath('//*[@id="main"]/div[3]/div/div[2]/div[2]/div[1]/div//text()').extract()
        job_desc = "".join(job_desc)

        # 对象属性赋值
        item["job_desc"] = job_desc

        # 提交item对象到Pipeline
        yield item

 

posted @ 2019-08-08 20:07  Amorphous  阅读(458)  评论(0编辑  收藏  举报