scrapy框架的日志等级和请求传参
scrapy框架的日志等级和请求传参
日志等级
在使用scrapy crawl spiderFileName运行程序时,在终端里打印输出的就是scrapy的日志信息。
日志信息的种类:
- ERROR : 一般错误
- WARNING : 警告
- INFO : 一般的信息
- DEBUG : 调试信息
设置日志信息指定输出:
在settings.py配置文件中,加入
LOG_LEVEL = ‘指定日志信息种类’即可。
LOG_FILE = 'log.txt'则表示将日志信息写入到指定文件中进行存储。
请求传参
应用: 当解析的数据不再同一个页面时
在某些情况下,我们爬取的数据不在同一个页面中,例如,我们爬取一个招聘网站,工作的岗位、薪水、公司在一级页面,而要爬取的岗位职责在其二级子页面中。这时我们就需要用到请求传参。
案例展示:爬取 https://www.zhipin.com/c100010000/?query=Python爬虫&page=1 boss招聘,将一级页面中的工作岗位、薪水、公司,二级页面中的岗位职责进行爬取。
spider
# -*- coding: utf-8 -*-
import scrapy
from scrapy.http.response.html import HtmlResponse
from scrapy_demo.items import ScrapyDemoItem
class BossSpider(scrapy.Spider):
name = 'boss'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://www.zhipin.com/c100010000/?query=Python%E7%88%AC%E8%99%AB&page=1']
url = 'https://www.zhipin.com/c100010000/?query=Python%E7%88%AC%E8%99%AB&page={}'
page_num = 1
def parse(self, response: HtmlResponse):
li_list = response.xpath('//div[@class="job-list"]/ul/li')
for li in li_list:
item = ScrapyDemoItem()
job_name = li.xpath('.//div[@class="job-title"]/text()').extract_first()
job_salary = li.xpath('.//div[@class="info-primary"]//span/text()').extract_first()
company = li.xpath('.//div[@class="info-company"]//h3/a/text()').extract_first()
item['job_name'] = job_name
item['job_salary'] = job_salary
item['company'] = company
detail_url = li.xpath('.//div[@class="info-primary"]//h3/a/@href').extract_first()
detail_url = 'https://www.zhipin.com' + detail_url
# 请求传参通过mete参数,引擎在回调时会自动将参数填入相应 response.meta 中
yield scrapy.Request(url=detail_url, meta={'item': item}, callback=self.parse_detail)
if self.page_num < 3: # 爬取前三页
self.page_num += 1
next_url = self.url.format(self.page_num)
yield scrapy.Request(url=next_url, callback=self.parse)
def parse_detail(self, response: HtmlResponse):
# 拿到请求传参的 数据
item = response.meta['item']
job_sec = response.xpath('//div[@class="detail-content"]/div[1]//div[@class="text"]/text()').extract()
job_sec = ''.join(job_sec).strip()
item['job_sec'] = job_sec
return item
items
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class ScrapyDemoItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
job_name = scrapy.Field()
job_salary = scrapy.Field()
company = scrapy.Field()
job_sec = 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://docs.scrapy.org/en/latest/topics/item-pipeline.html
class ScrapyDemoBossPipeline(object):
def __init__(self):
self.fp = None # 定义一个文件描述符
# 开始爬虫时,执行一次
def open_spider(self, spider):
print('爬虫开始')
self.fp = open('./boss.txt', 'w', encoding='utf8')
# 因为该方法会被执行调用多次,所以文件的开启和关闭操作写在了另外两个只会各自执行一次的方法中。
def process_item(self, item, spider):
# 将爬虫程序提交的item进行持久化存储
self.fp.write(f"job_name:{item['job_name']},job_salary:{item['job_salary']},company:{item['company']}"
f",job_sec:{item['job_sec']}\n")
return item
# 开始结束时,执行一次
def close_spider(self, spider):
self.fp.close()
print('爬虫结束')
settings
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'
ROBOTSTXT_OBEY = False
ITEM_PIPELINES = {
'scrapy_demo.pipelines.ScrapyDemoBossPipeline': 300,
}