python爬虫Scrapy(一)-我爬了boss数据
一、概述
学习python有一段时间了,最近了解了下Python的入门爬虫框架Scrapy,参考了文章Python爬虫框架Scrapy入门。本篇文章属于初学经验记录,比较简单,适合刚学习爬虫的小伙伴。
这次我选择爬取boss直聘的招聘信息数据,毕竟这个网站的数据还是很有参考价值的,下面我们讲述怎么爬取boss直聘的招聘信息并存盘,下一篇文章我们在对爬取到的数据进行分析。
二、Scrapy框架使用步骤
下面我们做一个简单示例,创建一个名字为BOSS的爬虫工程,然后创建一个名字为zhipin的爬虫来爬取zhipin.com这个网站
创建工程步骤:
1、创建工程 scrapy startproject BOSS
2、创建爬虫程序 cd BOSS 回车 scrapy gensipder zhipin zhipin.com
3、编写数据存储模板items.py 类对象继承自scrapy.item
4、编写爬虫zhipin.py 类对象集成子scrapy.Spider
5、修改settings.py配置文件 ITEM_PIPELINES = {'BOSS.pipelines.WwwZhipinComPipeline':100}
6、编写数据处理脚本进行数据保存,pipelines.py 类对象继承自object
def process_item(self, item, spider):
with open("my_boss.txt", 'a') as fp:
fp.write(item['name'] + '\n')
7、执行爬虫 cd BOSS 回车 scrapy crawl zhipin --nolog
注意:如果导出的中文信息乱码则需要在settings.py文件中配置编码:FEED_EXPORT_ENCODING = 'utf-8'
三、环境安装
爬虫框架我们使用Scrapy,爬取到的数据我们使用mongodb来存储
1、安装Scrapy
pip install Scrapy
2、安装mongodb
pip install pymongo
如果安装速度太慢,或者安装失败可以尝试使用pip install pymongo -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
mongodb基础操作命令参考:MongoDB基本命令操作
上述操作只是安装了mongodb的python驱动程序,如果要成功存储数据还需要安装Mongodb,具体安装流程参考Windows平台安装MongoDB,安装完成后一定要记得使用命令启动mongodb服务:net start MongoDB
四、mongodb使用
上一小节我们已经安装了mongodb数据库和驱动,因此后续我们爬取到的招聘信息就存储在该数据库中,为了方便数据存储,我们这里封装了一个类,来快速的访问数据库,代码如下所示
from pymongo import MongoClient class my_connect(object):
def __init__(self, settings):
try:
self.conn = MongoClient(settings["ip"], settings["port"])
except Exception as e:
print(e)
self.db = self.conn[settings["db_name"]]
self.my_set = self.db[settings["set_name"]] def insert(self, dic):
self.my_set.insert(dic) def update(self, dic, newdic):
self.my_set.update(dic, newdic) def delete(self, dic):
self.my_set.remove(dic) def dbfind(self, dic):
return self.my_set.find(dic) def setTableName(self, name):
#print(u'修改当前使用集合:{}'.format(name))
self.my_set = self.db[name]
上述代码中我们封装了一个名为my_connect的类,并提供了输入、更新、删除和查找文档的接口,除此之外还提供了一个setTableName的接口,这个接口主要是用于往不同集合中插入文档数据。MongoDB 概念解析可以看这里。mongodb属于非关系型数据库,与关系型数据库对比图如下
my_connect初始化函数中有一个参数,需要我们传入ip地址、端口号、数据库名字和集合名字,使用方式如下所示
from pymongo import MongoClient
from my_connect import my_connect settings = {
"ip":'127.0.0.1', #ip
"port":27017, #端口
"db_name" : "zhipin_datas", #数据库名字
"set_name" : "test" #集合名字
} conn = my_connect(settings)
conn.setTableName('')
conn.insert({'':''})
五、创建爬虫zhipin
1、输入如下命令,创建zhipin爬虫
scrapy startproject www_zhipin_com
cd www_zhipin_com 回车 scrapy gensipder zhipin www.zhipin.com
2、修改zhipin.py,爬取数据,类中成员属性含义代码中都有解释,这里不做解释,需要注意的是parse方法,该方法是爬取到数据以后的回调函数,参数response表示爬取到的结果,我们可以对其进行解析拿到网页数据。
class ZhipinSpider(scrapy.Spider):
# spider的名字定义了Scrapy如何定位(并初始化)spider,所以其必须是唯一的。
# 不过您可以生成多个相同的spider实例(instance),这没有任何限制。
# name是spider最重要的属性,而且是必须的
name = 'zhipin' # 可选。包含了spider允许爬取的域名(domain)列表(list)。
# 当 OffsiteMiddleware 启用时, 域名不在列表中的URL不会被跟进。
allowed_domains = ['www.zhipin.com'] # URL列表。当没有指定特定的URL时,spider将从该列表中开始进行爬取。
# 这里我们进行了指定,所以不是从这个 URL 列表里爬取
start_urls = ['http://www.zhipin.com/'] #网址URL中特殊字符转义编码:https://blog.csdn.net/u010828718/article/details/50548687
#爬取的页面,可以改为自己需要搜的条件,这里搜的是 北京-C++,其他条件都是不限
#query:查询岗位
#period:时间范围 5表示一个月内 &在url中需要写为%26
#a_街道b_区名称 eg:a_上地-b_海淀区 包含在路径内,城市编号(c101010100)下一级
positionUrl = 'https://www.zhipin.com/c101010100/?query=C%2B%2B%'
curPage = 1
解析数据时,默认一次可以拿到30条数据,我们循环遍历这30条数据,构造WwwZhipinComItem对象item,然后调用yield item即可
def parse(self, response):
job_list = response.css('div.job-list > ul > li')
request_data = []
for job in job_list:
item = WwwZhipinComItem()
...
yield item
2.1、这里有一个小技巧,我们重写start_requests方法,让他调用了我们自己写的一个方法next_request,并设置了回调函数为parse方法,当parse数据解析完毕后,又构造一个新的url在次调用next_request方法拉取数据,一直循环迭代,拉取数据、解析数据
2.2、boss直聘有一个限制,不管以什么样的方式搜索数据,数据最多显示10页,这也就要求我们需要对爬虫做一个处理,在合适的实际去终止拉取数据,否则爬虫会一直运行下去,直到boss直聘返回异常(请求被限制)
2.3、经过对爬虫数据的分析,我们发现当最后一次请求和上一次请求的数据完全一样时,我们可能已经到达请求的最后一页,那么这个时候我们就可以去终止爬虫了
2.4、为了快速的比对我么爬取到的数据是否和上一次一样,我们对爬取到的数据进行简单的处理,每次去对比关键字段即可
class itemData(object):
def __init__(self, data):
self.companyShortName = data['companyShortName']
self.positionName = data['positionName']
self.time = data['time']
self.city = data['city'] def __eq__(self, other):
return (self.positionName == other.positionName
and self.companyShortName == other.companyShortName
and self.time == other.time
and self.city == other.city) def __str__(self):
return "{}:{}:{}:{}".format(self.companyShortName
, self.time
, self.city
, self.positionName)
itemData包含是一条招聘信息,存储了招聘公司名称,职位名称,发布时间和发布城市,我们重写了__eq__方法,就是为了比对两个对象是否相等。
2.5、一次请求的数据是一个itemData集合,当两个集合相等时我们即可终止爬虫
if one_request == request_data:#已经拉取到最后一页数据了 退出
print('{}:本次拉取数据和上次拉取数据相同,{}'.format(time.strftime("%Y-%m-%d %H:%M:%S"
, time.localtime()), self.curPage))
return one_request = request_data #更新最后一次请求数据 print('{}:拉取数据量:{}'.format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), len(job_list)))
self.curPage += 1
time.sleep(5) # 停停停!听听听!都给我停下来听着!睡一会(~﹃~)~zZ
yield self.next_request()
2.6、parse解析数据时,对每一条数据会构造一个WwwZhipinComItem对象item,并通过yield item方式触发
3、对于爬取的字段定义需要我们修改item.py文件,定义爬取字段如下
class WwwZhipinComItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
pid = scrapy.Field()
positionName = scrapy.Field()
positionLables = scrapy.Field()
workYear = scrapy.Field()
salary = scrapy.Field()
city = scrapy.Field()
education = scrapy.Field()
companyShortName = scrapy.Field()
industryField = scrapy.Field()
financeStage = scrapy.Field()
companySize = scrapy.Field()
time = scrapy.Field()
updated_at = scrapy.Field()
4、最后一步写入数据库
4.1、第四节我们封装了一个名字为my_connect的数据库操作对象,在这里我们就可以用上了。
4.2、首先构造一个conn对象
db_name = 'zhipin_datas_C++'
nowMonth = datetime.datetime.now().month
settings = {
"ip":'127.0.0.1', #ip
"port":27017, #端口
"db_name" : db_name, #数据库名字
"set_name" : "test" #集合名字
} conn = my_connect(settings)
4.3、指定要插入的集合,然后构造数据、插入数据
conn.setTableName(month) data = {"pid": item['pid']#"27102804"
, "positionName": item['positionName']
, "positionLables": item['positionLables']#[]
, "workYear": item['workYear']#"5-10年"
, "salary": item['salary']#"30k-50k"
, "city": item['city']#"北京 海淀区 知春路"
, "education": item['education']#"硕士"
, "companyShortName": item['companyShortName']#"vmware"
, "industryField": item['industryField']#"计算机软件"
, "financeStage": item['financeStage']#"已上市"
, "companySize": item['companySize']#"10000人以上"
, "time": item['time']#"2018-11-13 17:35:02"
, "updated_at": item['updated_at']#"2018-11-13 17:35:02"
} conn.insert(data)
4.4、数据爬取结束后,使用gui工具Navicat 12 for MongoDB可以查看爬取到的数据,效果如下图所示
六、源码下载
需要全部代码的到csdn直接下载:python爬虫Scrapy(一)-我爬了boss数据
![]() |
![]() |
很重要--转载声明
- 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords
- 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。
python爬虫Scrapy(一)-我爬了boss数据的更多相关文章
- python爬虫scrapy框架——人工识别登录知乎倒立文字验证码和数字英文验证码(2)
操作环境:python3 在上一文中python爬虫scrapy框架--人工识别知乎登录知乎倒立文字验证码和数字英文验证码(1)我们已经介绍了用Requests库来登录知乎,本文如果看不懂可以先看之前 ...
- python爬虫项目(scrapy-redis分布式爬取房天下租房信息)
python爬虫scrapy项目(二) 爬取目标:房天下全国租房信息网站(起始url:http://zu.fang.com/cities.aspx) 爬取内容:城市:名字:出租方式:价格:户型:面积: ...
- python爬虫scrapy项目详解(关注、持续更新)
python爬虫scrapy项目(一) 爬取目标:腾讯招聘网站(起始url:https://hr.tencent.com/position.php?keywords=&tid=0&st ...
- Python爬虫实战二之爬取百度贴吧帖子
大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 前言 亲爱的们,教程比较旧了,百度贴吧页面可能改版,可能代码不 ...
- Python爬虫实战一之爬取糗事百科段子
大家好,前面入门已经说了那么多基础知识了,下面我们做几个实战项目来挑战一下吧.那么这次为大家带来,Python爬取糗事百科的小段子的例子. 首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把 ...
- 转 Python爬虫实战二之爬取百度贴吧帖子
静觅 » Python爬虫实战二之爬取百度贴吧帖子 大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 本篇目标 ...
- 转 Python爬虫实战一之爬取糗事百科段子
静觅 » Python爬虫实战一之爬取糗事百科段子 首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把,这次我们尝试一下用爬虫把他们抓取下来. 友情提示 糗事百科在前一段时间进行了改版,导致 ...
- python爬虫学习01--电子书爬取
python爬虫学习01--电子书爬取 1.获取网页信息 import requests #导入requests库 ''' 获取网页信息 ''' if __name__ == '__main__': ...
- python爬虫:了解JS加密爬取网易云音乐
python爬虫:了解JS加密爬取网易云音乐 前言 大家好,我是"持之以恒_liu",之所以起这个名字,就是希望我自己无论做什么事,只要一开始选择了,那么就要坚持到底,不管结果如何 ...
随机推荐
- Net Core 生成图形验证码
1. NetCore ZKweb 在我第一次绘制图形验证码时是采用的ZKweb的绘制库,奉上代码参考 public byte[] GetVerifyCode(out string ...
- mint-ui之picker爬坑记
picker的数据来源为动态获取时,数据无法正常渲染!因为方法不对,所以坑大了!深刻地体会到'业不精,我之过',谨以此文,深刻地记录一下踩坑及爬坑的整个过程,以便日后不再入坑,也给后来者提供一下参考 ...
- ionic常见问题及解决方案
1.Android SDK install设置代理服务器mirrors.neusoft.edu.cn80force http 2.ionic build android 2.1 gradle下载不了解 ...
- 【转】Fundebug上线微信小游戏错误监控!支持自动截屏!
摘要: Fundebug竭诚为你的小游戏保驾护航. 想必大家都玩过"跳一跳"吧?刷排行榜的感觉是不是很好啊!还有"知乎答题王"呢,在智力上碾压老铁简直太棒了! ...
- PAT1047: Student List for Course
1047. Student List for Course (25) 时间限制 400 ms 内存限制 64000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...
- eclipse常用快捷键(windows下)
## eclipse常用快捷键(windows下) ## 保存 1.保存当前代码页: ctrl + s 2.保存所有代码页: ctrl + shift + s 代码补全与修正 1.代码快速修正: ct ...
- (转)JAVA HashSet 去除重复值原理
Java中的set是一个不包含重复元素的集合,确切地说,是不包含e1.equals(e2)的元素对.Set中允许添加null.Set不能保证集合里元素的顺序. 在往set中添加元素时,如果指定元素不存 ...
- Linux kernel的中断子系统之(三):IRQ number和中断描述符
返回目录:<ARM-Linux中断系统>. 总结: 二描述了中断处理示意图,以及关中断.开中断,和IRQ number重要概念. 三介绍了三个重要的结构体,irq_desc.irq_dat ...
- C语言实现计算双基回文数详解
双基回文数的定义: 如果一个正整数n至少在两个不同的进位制(二进制<=进制=<十进制)b1和b2下都是回文数,则称n是双基回文数. 根据定义,简单的说就是在二进制到十进制之间(包括十进制和 ...
- mysql物理备份基本操作
Ⅰ.xtrabackup介绍 xtrabackup只能备份innodb引擎的数据,不能备份表结构,percona开源的,强烈推荐最新版本(旧版本bug多) innobackupex可以备份myisam ...