scrapy抓取拉勾网职位信息(七)——数据存储(MongoDB,Mysql,本地CSV)

时间:2022-08-27 16:59:45

上一篇完成了随机UA和随机代理的设置,让爬虫能更稳定的运行,本篇将爬取好的数据进行存储,包括本地文件,关系型数据库(以Mysql为例),非关系型数据库(以MongoDB为例)。

实际上我们在编写爬虫rules规则的时候,做了很多的限定,而且没有对翻页进行处理,所以最终提取的信息数量比较少,经我的测试,总共只有4k多条职位。如果要进行数据分析的话,数量量必须要足够,因此我们先将爬虫规则进行修改。

修改lagou_c.py文件rules

rules = (
Rule(LinkExtractor(allow=r'zhaopin/.*/')), #首页职位列表
Rule(LinkExtractor(allow=r'gongsi/j\d+.html')), #公司职位列表
Rule(LinkExtractor(allow=r'jobs/list_.*',restrict_css='.menu-box')), #校园职位列表
        Rule(LinkExtractor(allow=r'jobs/\d+.html'),callback='parse_item',follow=True), #详情页继续跟进,因为详情页包含其他的职位推荐,跟进后也是详情页 )

一、数据存储到MongoDB

如果没有MongoDB请先安装,并进行相应配置,并且启动MongoDB服务(出现connect network is unreachable一般都是没有开启服务造成的)


分析:要想把数据放进MongoDB,跟把大象放进冰箱是一样的道理。先连接数据库,把数据存进去,然后把连接关掉。

  • 我们在pipelines.py文件下新建一个类,MongoPipeline,这个类包括三个函数,open_spider(),process_item(),close_spider()
import pymongo  #第三方包pymongo,用来连接mongodb数据库并对其操作

class MongoPipeline(object):
def open_spider(self,spider): #开启爬虫的时候连接数据库
passdef process_item(self,item,spider): #运行爬虫的时候把item数据插入到数据库中
passdef close_spider(self,spider): #爬虫关闭的时候把数据库的连接断开
pass
  • 为了让代码更易扩展,我们不把mongodb的地址和名称写在这里,改为写在settings.py文件中,通过crawler来进行获取
class MongoPipeline(object):
def __init__(self,mongo_uri,mongo_db):
self.mongo_uri = mongo_uri #定义实例变量mongo_uri和mongo_db
self.mongo_db = mongo_db @classmethod
'''
这个类方法就是为了使用crawler来获取全局settings中的MONGO_URI和MONGO_DB的值,并复制给mongo_uri和mongo_db
'''
def from_crawler(cls,crawler):
return cls(
mongo_uri=crawler.settings.get('MONGO_URI'),
mongo_db=crawler.settings.get('MONGO_DB')
) def open_spider(self,spider):
self.client = pymongo.MongoClient(self.mongo_uri) #与数据库建立连接
self.db = self.client[self.mongo_db] #打开数据库 def process_item(self,item,spider):
self.db[item.collection].insert(dict(item)) #我这里直接获取item.collection字段,而collection我在items.py文件中赋值为’jobs‘,将item数据插入进去
return item #这个item返回才能被其他的中间件获取 def close_spider(self,spider):
self.client.close() #关闭数据库连接
  • 修改settings.py文件,增加MONGO_URI和MONGO_DB的定义,并且将MongoPipleline激活
ITEM_PIPELINES = {
#'lagou.pipelines.LagouPipeline': 300,
'lagou.pipelines.MongoPipeline': 333,
} MONGO_URI = 'localhost'
MONGO_DB = 'lagou'
  • 修改items.py文件,增加collection字段
import scrapy

class LagouItem(scrapy.Item):
collection = 'jobs'
#其他字段不做修改

这样我们就建立了一个与本地MongoDB的连接,数据库名称是lagou,存入的表collection名称是jobs。我们现在可以运行程序。

一段时间后,使用可视话工具查看,就可以看到数据被存储进了MongoDB数据库。

scrapy抓取拉勾网职位信息(七)——数据存储(MongoDB,Mysql,本地CSV)

scrapy抓取拉勾网职位信息(七)——数据存储(MongoDB,Mysql,本地CSV)

二、数据存储到Mysql

分析:思路与数据存储到MongoDB是一样的,只不过Mysql需要创建表,对各个字段进行定义

  • 我们手动创建一个数据库

scrapy抓取拉勾网职位信息(七)——数据存储(MongoDB,Mysql,本地CSV)

  • 进入这个lagou数据库,并且建立一个表

scrapy抓取拉勾网职位信息(七)——数据存储(MongoDB,Mysql,本地CSV)

  • 使用desc jobs;查看我们建立好的表。

scrapy抓取拉勾网职位信息(七)——数据存储(MongoDB,Mysql,本地CSV)

  • 开始写爬虫的代码,因为和mongodb的比较类似,我这里直接给出代码
import pymysql

class MysqlPipeline(object):
def __init__(self, host, database, user, password, port):
self.host = host
self.database = database
self.user = user
self.password = password
self.port = port @classmethod
def from_crawler(cls, crawler):
return cls(
host=crawler.settings.get('MYSQL_HOST'),
database=crawler.settings.get('MYSQL_DATABASE'),
user=crawler.settings.get('MYSQL_USER'),
password=crawler.settings.get('MYSQL_PASSWORD'),
port=crawler.settings.get('MYSQL_PORT'),
) def open_spider(self, spider):
self.db = pymysql.connect(host=self.host, database=self.database, user=self.user, password=self.password, port=self.port, charset='utf8')
self.cursor = self.db.cursor() def process_item(self, item, spider):
’‘’
这里直接使用值传入也可以,我这里直接把item生成一个字典传入
‘’‘
data = dict(item)
keys = ','.join(data.keys())
values = ','.join(['%s'] * len(data))
#sql = 'insert into jobs (url,name,ssalary,esalary,location,syear,eyear,edu_background,type,tags,release_time,advantage,job_desc,work_addr,company) values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'
sql = 'insert into jobs (%s) values (%s)' % (keys,values)
try:
#self.cursor.execute(sql, (item['url'],item['name'],item['ssalary'],item['esalary'],item['location'],item['syear'],item['eyear'],item['edu_background'],item['type'],item['tags'],item['release_time'],item['advantage'],item['job_desc'],item['work_addr'],item['company']))
self.cursor.execute(sql, tuple(data.values()))
self.db.commit()
except Exception as e:
print(e)
self.db.rollback()
return item def close_spider(self, spider):
self.db.close()
  • settings.py文件编写,增加mysql地址和端口等相关字段,并且激活MysqlPipeline
ITEM_PIPELINES = {
#'lagou.pipelines.LagouPipeline': 300,
#'lagou.pipelines.MongoPipeline': 300,
'lagou.pipelines.MysqlPipeline': 300,
} MYSQL_HOST = 'localhost'
MYSQL_DATABASE = 'lagou'
MYSQL_USER = 'root'
MYSQL_PASSWORD = ''
MYSQL_PORT = 3306

  • 运行代码一段时间,用可视化工具打开看一下,发现数据已经存进来了

scrapy抓取拉勾网职位信息(七)——数据存储(MongoDB,Mysql,本地CSV)

 三、数据存储到本地csv文件

分析:因为已经对数据进行了处理,所以保存文件到本地不需要再到pipeline里面去进行。

使用命令行的方式:

  • 运行爬虫时使用 scrapy crawl lagou_c -o lagou_jobs.csv,就可以保存一个名为lagou_jobs.csv文件到本地啦。

修改main.py文件的方式(本质上也是调用了命令行):

from scrapy import cmdline

cmdline.execute('scrapy crawl lagou_c -o lagou_jobs.csv'.split())

这样我们就分别完成了MongoDB,Mysql以及本地的存储。

scrapy抓取拉勾网职位信息(七)——数据存储(MongoDB,Mysql,本地CSV)的更多相关文章

  1. scrapy抓取拉勾网职位信息(一)——scrapy初识及lagou爬虫项目建立

    本次以scrapy抓取拉勾网职位信息作为scrapy学习的一个实战演练 python版本:3.7.1 框架:scrapy(pip直接安装可能会报错,如果是vc++环境不满足,建议直接安装一个visua ...

  2. scrapy抓取拉勾网职位信息(七)——实现分布式

    上篇我们实现了数据的存储,包括把数据存储到MongoDB,Mysql以及本地文件,本篇说下分布式. 我们目前实现的是一个单机爬虫,也就是只在一个机器上运行,想象一下,如果同时有多台机器同时运行这个爬虫 ...

  3. scrapy抓取拉勾网职位信息(三)——爬虫rules内容编写

    在上篇中,分析了拉勾网需要跟进的页面url,本篇开始进行代码编写. 在编写代码前,需要对scrapy的数据流走向有一个大致的认识,如果不是很清楚的话建议先看下:scrapy数据流 本篇目标:让拉勾网爬 ...

  4. scrapy抓取拉勾网职位信息(二)——拉勾网页面分析

    网站结构分析: 四个大标签:首页.公司.校园.言职 我们最终是要得到详情页的信息,但是从首页的很多链接都能进入到一个详情页,我们需要对这些标签一个个分析,分析出哪些链接我们需要跟进. 首先是四个大标签 ...

  5. scrapy抓取拉勾网职位信息(四)——对字段进行提取

    上一篇中已经分析了详情页的url规则,并且对items.py文件进行了编写,定义了我们需要提取的字段,本篇将具体的items字段提取出来 这里主要是涉及到选择器的一些用法,如果不是很熟,可以参考:sc ...

  6. scrapy抓取拉勾网职位信息(八)——使用scrapyd对爬虫进行部署

    上篇我们实现了分布式爬取,本篇来说下爬虫的部署. 分析:我们上节实现的分布式爬虫,需要把爬虫打包,上传到每个远程主机,然后解压后执行爬虫程序.这样做运行爬虫也可以,只不过如果以后爬虫有修改,需要重新修 ...

  7. scrapy抓取拉勾网职位信息(六)——反爬应对(随机UA,随机代理)

    上篇已经对数据进行了清洗,本篇对反爬虫做一些应对措施,主要包括随机UserAgent.随机代理. 一.随机UA 分析:构建随机UA可以采用以下两种方法 我们可以选择很多UserAgent,形成一个列表 ...

  8. scrapy抓取拉勾网职位信息(五)——代码优化

    上一篇我们已经让代码跑起来,各个字段也能在控制台输出,但是以item类字典的形式写的代码过于冗长,且有些字段出现的结果不统一,比如发布日期. 而且后续要把数据存到数据库,目前的字段基本都是string ...

  9. 【图文详解】scrapy爬虫与动态页面——爬取拉勾网职位信息(2)

    上次挖了一个坑,今天终于填上了,还记得之前我们做的拉勾爬虫吗?那时我们实现了一页的爬取,今天让我们再接再厉,实现多页爬取,顺便实现职位和公司的关键词搜索功能. 之前的内容就不再介绍了,不熟悉的请一定要 ...

随机推荐

  1. tomcat mysql 内存溢出的问题

    原因是mysql的密码有问题 解决办法: 具体操作步骤: 关闭 mysql: # service mysqld stop 然后: # mysqld_safe --skip-grant-tables 启 ...

  2. 图片上传安全性问题,根据ContentType (MIME) 判断其实不准确、不安全

    图片上传常用的类型判断方法有这么几种---截取扩展名.获取文件ContentType (MIME) .读取byte来判断(这个什么叫法来着?).前两种都有安全问题.容易被上传不安全的文件,如木马什么的 ...

  3. delphi7 编译程序时报win32.indcu.a病毒的解决方法

    Delphi7用了很久一直都没问题,同一个工程文件昨天编译时mod32还不会报毒,今天重新编译时,生成的exe突然nod32报毒. 提示: “Project1.exe Win32/Induc.A 病毒 ...

  4. php大力力 [016节] 兄弟连高洛峰php教程(2014年 14章数据库章节列表)

    2015-08-25 php大力力016 兄弟连高洛峰php教程(2014年 14章数据库章节列表) [2014]兄弟连高洛峰 PHP教程14.1.1 复习数据库  15:58 [2014]兄弟连高洛 ...

  5. 14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE

    14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE 回收操作系统磁盘空间当truncate 一个InnoDB ...

  6. 【足迹C++primer】40、动态数组

    动态数组 C++语言定义了第二种new表达式语法.能够分配并初始化一个对象数组.标准库中包括 一个名为allocator的类.同意我们将分配和初始化分离. 12.2.1 new和数组 void fun ...

  7. Oracle的over子函数的妙用

    摘要 oracle的over 子函数可实现按指定的字段分组排序,对于相同分组字段的结果集进行排序,其中PARTITION BY 为分组字段,ORDER BY 指定排序字段这对统计分析这类问题意想不到的 ...

  8. 服务器 : Apache Tomcat - 理解架构层次

    文章概览 相信很多接触java的人都对Tom猫有着多少的熟悉,就个人而言,本来只知道Tom简单的操作与配置,就像裹上一层纱,迷迷糊糊的. Tomcat的书籍本来就不多,高分的还是很久之前的版本,直到最 ...

  9. php小项目踩坑以及其中的注意点(第二篇)

    用户登录页面 1.通过数据库验证用户名和密码(可以将里面要用到的数据库信息,放入到一个config文件中) <?php define('DB_HOST','localhost'); define ...

  10. python java scala 单例模式

    Python class Single2(object): """ 同一个对象 """ __instance = None def __ne ...