scrapy基础知识之将item写入JSON文件,unicode如果用中文显示可以在pipelines中设置如下

本文介绍Scrapy框架中的日志配置方法及不同日志级别的含义,并解决了在使用Scrapy过程中遇到的日志级别问题。此外,还讲解了如何正确处理JSON文件中的中文编码问题,确保输出的JSON文件能正确显示中文。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


日志级别
Python的内置日志记录定义了5个不同的级别来指示给定日志消息的严重性。这里是标准的,按递减顺序列出:
  1. logging.CRITICAL - 严重错误(最严重)
  2. logging.ERROR - 经常出错
  3. logging.WARNING - 用于警告消息
  4. logging.INFO - 用于参考消息
  5. logging.DEBUG - 用于调试消息(最低严重性)


COOKIES_ENABLED = False
# 下载延迟限制
#DOWNLOAD_DELAY = 1
# 输出日志等级
#LOG_LEVEL = 'DEBUG'
#LOG_LEVEL = 'INFO'
# 不加以下设置以 json 格式打印
#LOG_LEVEL = 'ERROR'
LOG_LEVEL = 'CRITICAL'
=========================================================================
以 上错误Scrapy 版本问题。scrapy=1.5.0 改成 scrapy=1.4.0


2、scrapy基础知识之将item写入JSON文件,unicode如果用中文显示可以在pipelines中设置如下:

设置之后的结果:

在使用json.dumps时要注意一个问题
import json print json.dumps( '中国' ) # 输出结果:"\u4e2d\u56fd"
输出的会是'中国' 中的ascii 字符码,而不是真正的中文。
这是因为json.dumps 序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False:
import json print json.dumps( '中国' ) # 输出结果:"\u4e2d\u56fd" print json.dumps( '中国' ,ensure_ascii= False ) # 输出结果:"中国"
你要去看 open 第三个参数默认值是什么,因为默认不是 utf-8写的吧,就算内容编码了,不用 utf-8写也会乱码,估计是这样
============================================================================


### 实现Python爬虫抓取拉勾网招聘信息并存储至MySQL #### 使用Scrapy框架构建爬虫项目 为了高效地完成此任务,推荐使用Scrapy这一强大的Web爬虫框架。创建一个新的Scrapy项目来处理拉勾网的数据采集工作。 安装依赖包: ```bash pip install scrapy pymysql ``` 初始化新的Scrapy项目: ```bash scrapy startproject lagou_spider cd lagou_spider ``` 定义Item类用于表示每条记录中的字段,在`items.py`中添加如下代码: ```python import scrapy class LagouJobItem(scrapy.Item): title = scrapy.Field() # 职位名称 salary_min = scrapy.Field() # 最低薪资 salary_max = scrapy.Field() # 最高薪资 city = scrapy.Field() # 工作城市 work_years = scrapy.Field() # 经验要求 education = scrapy.Field() # 学历要求 job_advantage = scrapy.Field() # 职位诱惑 job_desc = scrapy.Field() # 岗位描述 company_name = scrapy.Field() # 公司名称 url = scrapy.Field() # 页面链接 url_object_id = scrapy.Field() # URL哈希值 ``` 编写Spider脚本解析网页内容,假设命名为`lagou_jobs.py`: ```python from urllib.parse import urlencode import json import re import scrapy from ..items import LagouJobItem from ArticleSpider.utils.common import get_md5 # 自定义工具函数获取URL MD5编码[^2] class LagouJobsSpider(scrapy.Spider): name = 'lagou_jobs' allowed_domains = ['www.lagou.com'] def __init__(self, *args, **kwargs): super(LagouJobsSpider, self).__init__(*args, **kwargs) def start_requests(self): base_url = "https://www.lagou.com/jobs/positionAjax.json?" params = { 'needAddtionalResult': False, 'isSchoolJob': None } for page_num in range(1, 3): # 控制翻页数量 form_data = {'first': True if page_num==1 else False,'pn': str(page_num), 'kd':''} yield scrapy.FormRequest(url=base_url + urlencode(params), method="POST", headers={ 'Referer': f'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput='}, body=json.dumps(form_data), callback=self.parse_job_listings) def parse_job_listings(self,response): results = json.loads(response.text)['content']['positionResult']['result'] for result in results: item = LagouJobItem() try: item['title'] = result.get('positionName') salary_range = result.get('salary').split('-') item['salary_min'],item['salary_max']= map(lambda s:s.strip('kK'),salary_range) if len(salary_range)==2 else (None,None) item['city'] = result.get('city') item['work_years'] = result.get('workYear') item['education'] = result.get('education') item['company_name'] = result.get('companyShortName') item['url'] = f"https://www.lagou.com/jobs/{result.get('positionId')}.html" item['url_object_id'] = get_md5(item['url']) detail_request = scrapy.Request( item['url'], meta={'item': item}, callback=self.parse_detail_page ) yield detail_request except Exception as e: print(f"Parsing Error:{e}") continue def parse_detail_page(self,response): item=response.meta['item'] try: item['job_advantage']="".join([i.strip()for i in response.xpath('//dd[@class="job-advantage"]/p/text()').extract()]) item['job_desc']="".join([i.strip().replace('\n',' ')for i in response.xpath('//div[contains(@class,"job-detail")]/text()|//div[contains(@class,"job-detail")]/*//text()').getall()]) except Exception as e: print(f"Detail Page Parsing Error:{e}") yield item ``` 配置Pipeline以支持向MySQL写入数据,在`settings.py`里激活pipeline组件,并设置数据库连接参数;编辑`pipelines.py`文件加入以下逻辑实现对MySQL的操作[^3]: ```python import pymysql.cursors from twisted.enterprise import adbapi from .items import LagouJobItem class MySQLTwistedPipeline(object): @classmethod def from_settings(cls, settings): db_params=dict( host=settings["MYSQL_HOST"], port=settings["MYSQL_PORT"], user=settings["MYSQL_USER"], password=settings["MYSQL_PASSWORD"], database=settings["MYSQL_DBNAME"], charset='utf8', cursorclass=pymysql.cursors.DictCursor, use_unicode=True, ) return cls(dbpool=adbapi.ConnectionPool("pymysql",**db_params)) def process_item(self,item,spider): query=self.dbpool.runInteraction(self.do_insert,item=item) query.addErrback(self.handle_error)#错误处理 return item def do_insert(self,cursor,item:LagouJobItem): insert_sql,params=""" INSERT INTO jobs(title,salary_min,salary_max,city,work_years,education,job_advantage,job_desc,company_name,url,url_object_id) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s); """,(item['title'],item['salary_min'],item['salary_max'],item['city'],item['work_years'],item['education'],item['job_advantage'],item['job_desc'],item['company_name'],item['url'],item['url_object_id']) cursor.execute(insert_sql,params) def handle_error(self,failure): spider.logger.error(str(failure)) ``` 最后修改项目的`settings.py`,确保已开启上述自定义管道服务,并填写好对应的MySQL服务器信息: ```python ITEM_PIPELINES = { 'your_project.pipelines.MySQLTwistedPipeline': 300, } # 配置MySQL连接详情 MYSQL_HOST = 'localhost' MYSQL_PORT = 3306 MYSQL_USER = '' MYSQL_PASSWORD = '' MYSQL_DBNAME = '' DOWNLOAD_DELAY = 1 # 设置下载延迟防止被封禁IP地址 COOKIES_ENABLED=False # 关闭cookies中间件因为某些情况下它可能会干扰请求头伪造 USER_AGENT='' # 可选:更改User-Agent模拟浏览器访问行为 ROBOTSTXT_OBEY = False # 不遵循robots协议以便能够遍历更多页面资源 ``` 通过以上步骤可以成功搭建起一个完整的基于Python Scrapy框架的网络爬虫应用案例,该应用程序可以从拉勾网上提取职位列表及其详细说明,并将其安全可靠地保存到本地运行着MySQL实例的关系型数据库表单之中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值