利用scrapy框架爬取某招聘网站,并对数据进行简单分析
利用scrapy框架爬取某招聘网站,并对数据进行简单分析
**
今天终于把老师之前布置的任务完成了,总算能干一些自己喜欢的事情,想到自己明年就要工作了。决定先利用之前为了搜集语料学习的爬虫去搜寻一些职位相关讯息,看看大家现在都在招什么样的工作。
目标网站 :
这个就很多辣,什么某直聘,某勾。依照至简至上的原则,在大概看了一下几个网站的情况,决定选取某b(某勾要登录验证,懒得去弄cookies了)。
大概的步骤就如下啦,scrapy框架是纯基于python写的,优点就是简单配置方便
- 创建spider的项目,这次模板我选了crawl模板;
- 对目标网站的信息读取,拟定好爬取哪些字段;
- 编写spider,包括页面提取规则,字段处理规则;
- 配置pipeline连接到数据库连接到;
- 配置好settings中的其他选项;
- 调试,开始爬取;
- 当然可能还有一些反反爬操作。
话不多说开撸。
首先是
在当前目录下(已经存在的scrapy项目)输入
scrapy genspider -t crawl boss_https://www.zhipin.com/
现在itenm创建所需要的item,里面有工作名啊,工资啊,公司名啊,地点啊还有工作描述和职位要求等等,具体如下最后三个表示公司人数、类型、级别(几轮融资等等)
然后 进入生成的boss.py
因为我选择的是crawl模型,所以网页提取规则是基于 规则提取,省了很多事,但也记得要范围限制好不然什么都爬
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from Douban.items import BOSSItem
import re
class BossSpider(CrawlSpider):
name = 'boss'
allowed_domains = ['zhipin.com']
start_urls = ['https://www.zhipin.com/c101280600/?query=%E6%B7%B1%E5%9C%B3&page=1&ka=page-1']
rules = (
Rule(LinkExtractor(allow=r'c101280600/?page=.*'),follow=True),
Rule(LinkExtractor(allow=r'c101280600/?query=深圳.*'),follow=True),
Rule(LinkExtractor(allow=r'job_detail/\w.*'), callback='parse_item', follow=True),
)
custom_settings = {
"COOKIES_ENABLED":False
#
}
这里规则限度开始页和拓展页都只选择深圳的企业,因为我发现就深圳工作已经够多了
当然要提取网页元素,怎么能少的了scrapy shell来调试呢,哪怕pycharm的debug模式再好用也比不过
def parse_item(self, response):
article_items = BOSSItem()
job = response.css('.info-primary h1:nth-child(1)::text').extract()[0]
company_name = response.css('.job-sec.prop-item+div h3+div::text').extract()[0]
salary = response.css('.info-primary span.salary::text').extract()[0]
salary = str(re.search(".*?(\d+.*\d)",salary).group(1)).strip().replace('-',',')
location = response.css('.info-primary>p::text').extract()[0]
experience = response.css('.info-primary>p::text').extract()[1]
edu = response.css('.info-primary>p::text').extract()[2]
job_content = response.css('.detail-content div:nth-child(2)::text').extract()[1]
job_requirement =response.css('.detail-content div:nth-child(2)::text').extract()[3]
com_num = response.css('.sider-company p:nth-child(4)::text').extract()[0]
com_type = response.css('a[ka="job-detail-brandindustry"]::text').extract()[0]
com_level = response.css('.sider-company p:nth-child(3)::text').extract()[0]
article_items['job'] = job
article_items['company_name'] = company_name
article_items['salary'] = salary
article_items['location'] = location
article_items['experience'] = experience
article_items['edu'] = edu
article_items['job_content'] = job_content
article_items['job_requirement'] = job_requirement
article_items['com_num'] = com_num
article_items['com_type'] = com_type
article_items['com_level'] = com_level
yield article_items
网页元素提取就如上了,无非就是css或者xpath,规则还是挺简单的,有人喜欢放到itenms里处理,但是我比较喜欢这样简单粗暴。看网页源码的话用fox浏览器比较方便。
因为薪水全部都是范围表示的,所以利用正则化匹配提取,还犯了几个错误就是提取工作内容的时候信息提取没弄好,到爬完了才发现少了不少的内容。另外location这个字段可以删除,因为我搜集的范围仅限于深圳。
#setting.py中
DOWNLOAD_DELAY = 0.9
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'Douban (+http://www.yourdomain.com)'
USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0"
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
ITEM_PIPELINES = {
'Douban.pipelines.MySqlTwistedPipeline': 3,
# "Douban.pipelines.GIFImagePipeline":2
# "scrapy.pipelines.images.ImagesPipeline":3
# "Douban.pipelines.GIFPipeline":3
}
DOWNLOAD_DELAY = 0.9
还有就配置setting和pipeline了,项目头是我之前爬豆瓣留下的
这个pipeline作用是采用异步机制传输数据到mysql
class MySqlTwistedPipeline(object):
def __init__(self,dbpool):
self.dbpool = dbpool
@classmethod
def from_settings(cls,settings):
dbparms = dict(
host = settings['MYSQL_HOST'],
db = settings['MYSQL_DBNAME'],
user = settings['MYSQL_USER'],
passwd = settings['MYSQL_PASSWORD'],
charset='utf8',
cursorclass = MySQLdb.cursors.DictCursor,
use_unicode=True
)
#dbpool = adbapi.ConnectionPool('MySQLdb',**dbparms)
dbpool = adbapi.ConnectionPool("MySQLdb", **dbparms)
return cls (dbpool)
def process_item(self,item,spider):
query = self.dbpool.runInteraction(self.do_insert,item)
query.addErrback(self.handle_error)
def handle_error(self,failure):
print(failure)
def do_insert(self,cursor,item):
insert_sql = '''
insert into boss_copy(job,company_name,salary,location,experience,edu,job_content,job_requirement,com_num,com_type,com_level)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
''' (item["title"],item["url"],item["url_object_id"],item["front_image_url"],item["front_image_path"],item["comment_num"],item["fav_num"],item["like_num"],item["time_tag"],item["content"],item["tag_label"]))
cursor.execute(insert_sql,(item["job"],item["company_name"],item["salary"],item["location"],item["experience"],item["edu"],item["job_content"],item["job_requirement"],item["com_num"],item['com_type'],item['com_level']))
接下来就直接通过main函数可以开爬了
main
# -*- coding: utf-8 -*-
from scrapy.cmdline import execute
import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# execute(["scrapy", "crawl", "mt"])
# execute(["scrapy", "crawl", "Douban_spider"])
execute(["scrapy", "crawl", "boss"])
意向不到的是整个过程异常的流畅,差不多一步到位
嗯??什么反爬都没准备吗?是对自己数据不关心或是生意不好?有点摸不着头脑
我慢慢将delay降到了0.5
考虑到自己不赶时间,就没毕要去探下限了。
想起当时为了做实验和淘宝天猫反反爬的日子心就象在滴血T T,后来还是花了几块钱用了阿里云ip才成功,阿里连我这几块钱都不放过。
大概花了几个小时,数据库的结果已经有两万多了,看到一些边缘数据已经没有意义了,于是手动停止。
引用文本
大概就是这样子
看的出来在职位描述和要求里漏了不少内容
用seaborn包随意做了点分析
类别没有排好序
可以说旱的旱死,laodelaos了
这里普遍是指 “以上
zZG4ubmV0L3dlaXhpbl80MDY0NDI5OA==,size_16,color_FFFFFF,t_70)
这个可能更直观
最后得到结论就是高薪资工作普遍和公司规模、学历、经验都成正相关(废话),
而最重要的因素是
经验!!!相关系数达到0.5(说好的老程序员困境呢?)
且薪资普遍较高的是都是大互联网公司(基数也最多)鹅厂招有经验程序员最大方、今日头条给的也多系,其次就是金融、互联网金融(深圳最多了)
最后
利用得到的职位要求,按照出现频率 利用python工具获得了一互联网岗位要求中的热词
1.JAVA
2.c++
3.前端(web,感觉安卓和ios奇缺)
4.数据库、大数据sprk hadoop
5.python、r
不用说了,毕业即失业,人间不值得T T
ps:数据集在这有需要拿去吧
https://pan.baidu.com/s/1zwHHEQ7wTSRVCrJwU7k0Xg
密码:mbvh
上一篇: 爬取qq好友说说并对数据简单分析