文档章节

Python scrapy爬虫爬取前程无忧的职位信息,并简要数据分析

zhaobig
 zhaobig
发布于 2017/09/11 20:49
字数 1025
阅读 64
收藏 0
点赞 0
评论 0
爬取python、java、html在北京的工作岗位,写入数据库,写入csv文件,并统计北京各个区的工作岗位数量,各个薪资水平的数量,以 柱状图/直方图展示

进入终端 scrapy startproject 项目名称
Pycharm打开项目
编写蜘蛛
spider代码:
# -*- coding: utf-8 -*-
import scrapy
from ..items import JobsItem

class JobSpider(scrapy.Spider):
    name = 'job'
    allowed_domains = ['51job']
    start_urls = ['http://search.51job.com/list/010000,000000,0000,00,9,99,python,2,1.html','http://search.51job.com/list/010000,000000,0000,00,9,99,java,2,1.html','http://search.51job.com/list/010000,000000,0000,00,9,99,html,2,1.html']

    def parse(self, response):
        # 1.本页数据重新发起请求,进行解析
        yield scrapy.Request(
            url=response.url,
            callback=self.parse_detail,
            # 指定是否参与去重,默认值False
            # 改为True,不参与去重
            dont_filter=True
        )


    def parse_detail(self,response):

        # 2.找到下一页按钮
        next_page = response.xpath("//li[@class='bk'][2]/a/@href")

        if next_page:
            # 发起请求
            yield scrapy.Request(
                url=next_page.extract_first(''),
                callback=self.parse_detail,
                # 不参与去重
                dont_filter=True
            )

        # 找到所有的工作岗位标签
        jobs = response.xpath("//div[@id='resultList']/div[@class='el']")
        for job in jobs:
            # 薪资
            job_money = job.xpath("span[@class='t4']/text()").extract_first('')
            # 把按月薪万或千的数据拿回来
            if '月' in job_money:
                if '千' in job_money:
                    money = job_money.split('千')[0]
                    min_money = float(money.split('-')[0])*1000
                    max_money = float(money.split('-')[1])*1000
                elif '万' in job_money:
                    money = job_money.split('万')[0]
                    min_money = float(money.split('-')[0])*10000
                    max_money = float(money.split('-')[1])*10000
                else:
                    continue
            else:
                continue
            # 工作名称
            job_name = job.xpath("p/span/a/@title").extract_first('')
            # 详情地址
            detail_url = job.xpath("p/span/a/@href").extract_first('')
            # 公司名称
            company_name = job.xpath("span[@class='t2']/a/text()").extract_first('')
            # 工作地点
            job_place = job.xpath("span[@class='t3']/text()").extract_first('')
            # 发布日期
            job_date = job.xpath("span[@class='t5']/text()").extract_first('')

            item = JobsItem()
            item["job_name"] = job_name
            item["job_place"] = job_place
            item["detail_url"] = detail_url
            item["company_name"] = company_name
            item["job_date"] = job_date
            item["job_money"] = job_money
            item["max_money"] = max_money
            item["min_money"] = min_money
            yield item
item中创建数据模型类
class JobsItem(scrapy.Item):
    job_name = scrapy.Field()
    detail_url = scrapy.Field()
    company_name = scrapy.Field()
    job_place = scrapy.Field()
    job_date = scrapy.Field()
    job_money = scrapy.Field()
    min_money = scrapy.Field()
    max_money = scrapy.Field()
middlewares中设置请求头
from fake_useragent import UserAgent
from random import choice
class RandomUAMiddleware(object):
    def __init__(self,crawler):
        super(RandomUAMiddleware, self).__init__()
        self.crawler = crawler
        self.ua = UserAgent()
        self.ip_list = ['60.18.164.46:63000','61.135.217.7:80','123.7.38.31:9999']
    @classmethod
    def from_crawler(cls,crawler):

        return cls(crawler)
    # 处理请求函数
    def process_request(self,request,spider):
        # 随机产生请求头
        request.headers.setdefault('User-Agent',self.ua.random)
pipelines中设置写入数据库和csv文件
import csv
import codecs
class SaveCSVFile(object):
    def __init__(self):
        self.file_handle = codecs.open('jobs.csv','w',encoding='utf-8')
        # 1.创建csv文件
        self.csv = csv.writer(self.file_handle)
        self.csv.writerow(('job_name','detail_url','company_name','job_place','job_date','job_money','min_money','max_money'))

    def process_item(self,item,spider):

        self.csv.writerow((item['job_name'],item['detail_url'],item['company_name'],item['job_place'],item['job_date'],item['job_money'],item['min_money'],item['max_money']))

        return item

    def __del__(self):
        # 关闭文件
        self.file_handle.close()


from twisted.enterprise import adbapi
from MySQLdb import cursors

class MysqlTwistedPipeline(object):
    @classmethod
    # 这个函数会自动调用
    def from_settings(cls,settings):
        # 准备好连接数据库需要的参数
        db_params = dict(
            host = settings["MYSQL_HOST"],
            port = settings["MYSQL_PORT"],
            user = settings["MYSQL_USER"],
            passwd = settings["MYSQL_PASSWD"],
            charset = settings["MYSQL_CHARSET"],
            db = settings["MYSQL_DBNAME"],
            use_unicode = True,
            # 指定游标类型
            cursorclass=cursors.DictCursor
        )
        # 创建连接池
        # 1.要连接的名称  2.连接需要的参数
        db_pool = adbapi.ConnectionPool('MySQLdb',**db_params)
        # 返回当前类的对象,并且把db_pool赋值给该类的对象
        return cls(db_pool)

    def __init__(self,db_pool):
        # 赋值
        self.db_pool = db_pool

    # 处理item函数
    def process_item(self,item,spider):
        # 把要处理的事件进行异步处理
        # 1.要处理的事件函数
        # 2.事件函数需要的参数
        query = self.db_pool.runInteraction(self.do_insert,item)
        # 执行sql出现错误信息
        query.addErrback(self.handle_error,item,spider)
        return item
    # 错误的原因
    def handle_error(self,failure,item,spider):

        print failure

    # 处理插入数据库的操作
    # cursor该函数是连接数据库的函数,并且放在异步去执行,cursor执行sql语句
    def do_insert(self,cursor,item):
        # 1.准备sql语句
        sql = 'insert into job(job_name,detail_url,company_name,job_place,job_date,job_money,min_money,max_money)VALUES (%s,%s,%s,%s,%s,%s,%s,%s)'
        # 2.用cursor游标执行sql
        cursor.execute(sql, (item["job_name"], item["detail_url"], item["company_name"], item["job_place"], item["job_date"], item["job_money"],item["min_money"], item["max_money"]))
settings文件设置
DOWNLOADER_MIDDLEWARES = {
   'ZHB51Job.middlewares.RandomUAMiddleware': 100,
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None
}
ITEM_PIPELINES = {
   'JobsSpider.pipelines.MysqlTwistedPipeline': 300,
    'JobsSpider.pipelines.SaveCSVFile': 301,
}
MYSQL_HOST = '127.0.0.1'
MYSQL_PORT = 3306
MYSQL_DBNAME = 'jobs'
MYSQL_USER = 'root'
MYSQL_PASSWD = '123456'
MYSQL_CHARSET = 'utf8'
创建debug调试文件
from scrapy.cmdline import execute

execute(['scrapy','crawl','spider'])
创建数据分析文件

# -*- coding:utf-8 -*-
import sys
import matplotlib.pyplot as plt
import numpy
reload(sys)
sys.setdefaultencoding("utf-8")
import pandas as pd
df_obj = pd.read_csv('job.csv') 

# 北京各岗位的数量
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
number = df_obj.groupby(df_obj['job_place']).size()
print number
number.plot.bar()
plt.title('北京各地区岗位数量')
plt.xlabel('地区')
plt.ylabel('数量')
plt.savefig('job.png')
plt.show() 

# 薪资及数量分布图
df_obj1=df_obj[df_obj['max_money']>0]
max_money = df_obj1.groupby(df_obj1['max_money']).size()
max_money.plot.bar()
plt.title('各个薪资水平及数量')
plt.xlabel('薪资')
plt.ylabel('数量')
plt.savefig('pay.png')
plt.show()
展示图例如下


© 著作权归作者所有

共有 人打赏支持
zhaobig
粉丝 0
博文 5
码字总数 5529
作品 0
省直辖县级行政区划
一个月入门Python爬虫,快速获取大规模数据

数据是创造和决策的原材料,高质量的数据都价值不菲。而利用爬虫,我们可以获取大量的价值数据,经分析可以发挥巨大的价值,比如: 豆瓣、知乎:爬取优质答案,筛选出各话题下热门内容,探索...

Python开发者 ⋅ 04/25 ⋅ 0

高级爬虫(一):Scrapy爬虫框架的安装

Hi 小伙伴们差不多有半个月没有更新干货了,一直有点忙,而且这中间还有曲折过程,也就没有更新文章. 但今天无论如何也要更新一篇文章,接下来是爬虫高级篇重点讲解的地方! 最近会连载Scrap...

Python绿色通道 ⋅ 04/22 ⋅ 0

5.2 高富帅python-人工智能时代

小奈:其实你们写的代码好像有不同派系的? 大仁:你是说编程语言?我来介绍下吧,我们来看下GitHub(程序员同城交友、代码协作平台)的数据,看下各种编程语言 Pull Requst的数据, Javascr...

产品经理的技术课堂 ⋅ 05/11 ⋅ 0

Python利用Scrapy爬取智联招聘和前程无忧的招聘数据

爬虫起因   前面两个星期,利用周末的时间尝试和了解了一下Python爬虫,紧接着就开始用Scrapy框架做了一些小的爬虫,不过,由于最近一段时间的迷茫,和处于对职业生涯的规划。以及对市场需...

镇屌要逆袭 ⋅ 2017/12/08 ⋅ 0

Python3爬虫视频学习教程

大家好哈,现在呢静觅博客已经两年多啦,可能大家过来更多看到的是爬虫方面的博文,首先非常感谢大家的支持,希望我的博文对大家有帮助! 最近,主要的任务就是开发性感美女图片大全,使用p...

yangjiyue0520 ⋅ 2017/11/18 ⋅ 0

Python Scrapy 爬虫(四):部署与运行

接上篇,在上篇中,我们已经在服务器上搭建好了 Python3 环境以及对应的 virtualenv 虚拟环境了。接下来,我们开始把代码部署到我们的服务器环境并运行。 在部署我们的代码到服务器前,我们来...

雨林_a1d6 ⋅ 06/01 ⋅ 0

7个Python爬虫实战项目教程

有很多小伙伴在开始学习Python的时候,都特别期待能用Python写一个爬虫脚本,实验楼上有不少python爬虫的课程,这里总结几个实战项目,如果你想学习Python爬虫的话,可以挑选感兴趣的学习哦;...

实验楼 ⋅ 2017/12/05 ⋅ 0

5个python爬虫教材,让小白也有爬虫可写,含视频教程!

认识爬虫   网络爬虫,如果互联网是一张蜘蛛网,网络爬虫既是一个在此网上爬行的蜘蛛,爬了多少路程即获取到多少数据。 python写爬虫的优势   其实以上功能很多语言和工具都能做,但是用...

柯西带你学编程 ⋅ 06/12 ⋅ 0

[原创]手把手教你写网络爬虫(3):开源爬虫框架对比

原文出处:拓海 介绍 大家好!我们从今天开始学习开源爬虫框架Scrapy,如果你看过《手把手》系列的前两篇,那么今天的内容就非常容易理解了。细心的读者也许会有疑问,为什么不学出身名门的A...

拓海 ⋅ 04/28 ⋅ 0

python3 scrapy爬取智联招聘存mongodb

写在前面,这次写智联招聘的爬虫是其次,主要的是通过智联招聘上的数据信息弄一个数据挖掘的小项目,这一篇主要是如何一气呵成的将智联招聘上的招聘信息给爬下来 (一)scrapy框架的使用 sc...

徐代龙 ⋅ 05/01 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

发送短信如何限制1小时内最多发送11条短信

发送短信如何限制1小时内最多发送11条短信 场景: 发送短信属于付费业务,有时为了防止短信攻击,需要限制发送短信的频率,例如在1个小时之内最多发送11条短信. 如何实现呢? 思路有两个 截至到当...

黄威 ⋅ 昨天 ⋅ 0

mysql5.7系列修改root默认密码

操作系统为centos7 64 1、修改 /etc/my.cnf,在 [mysqld] 小节下添加一行:skip-grant-tables=1 这一行配置让 mysqld 启动时不对密码进行验证 2、重启 mysqld 服务:systemctl restart mysql...

sskill ⋅ 昨天 ⋅ 0

Intellij IDEA神器常用技巧六-Debug详解

在调试代码的时候,你的项目得debug模式启动,也就是点那个绿色的甲虫启动服务器,然后,就可以在代码里面断点调试啦。下面不要在意,这个快捷键具体是啥,因为,这个keymap是可以自己配置的...

Mkeeper ⋅ 昨天 ⋅ 0

zip压缩工具、tar打包、打包并压缩

zip 支持压缩目录 1.在/tmp/目录下创建目录(study_zip)及文件 root@yolks1 study_zip]# !treetree 11└── 2 └── 3 └── test_zip.txt2 directories, 1 file 2.yum...

蛋黄Yolks ⋅ 昨天 ⋅ 0

聊聊HystrixThreadPool

序 本文主要研究一下HystrixThreadPool HystrixThreadPool hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/HystrixThreadPool.java /** * ThreadPool used to executed {@link Hys......

go4it ⋅ 昨天 ⋅ 0

容器之上传镜像到Docker hub

Docker hub在国内可以访问,首先要创建一个账号,这个后面会用到,我是用126邮箱注册的。 1. docker login List-1 Username不能使用你注册的邮箱,要用使用注册时用的username;要输入密码 ...

汉斯-冯-拉特 ⋅ 昨天 ⋅ 0

SpringBoot简单使用ehcache

1,SpringBoot版本 2.0.3.RELEASE ①,pom.xml <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.3.RELE......

暗中观察 ⋅ 昨天 ⋅ 0

Spring源码解析(八)——实例创建(下)

前言 来到实例创建的最后一节,前面已经将一个实例通过不同方式(工厂方法、构造器注入、默认构造器)给创建出来了,下面我们要对创建出来的实例进行一些“加工”处理。 源码解读 回顾下之前...

MarvelCode ⋅ 昨天 ⋅ 0

nodejs __proto__跟prototype

前言 nodejs中完全没有class的这个概念,这点跟PHP,JAVA等面向对象的语言很不一样,没有class跟object的区分,那么nodejs是怎么样实现继承的呢? 对象 对象是由属性跟方法组成的一个东西,就...

Ai5tbb ⋅ 昨天 ⋅ 0

Ubuntu16.04 PHP7.0 不能用MYSQLi方式连接MySQL5.7数据库

Q: Ubuntu16.04 PHP7.0 不能用MYSQLi方式连接MySQL5.7数据库 A: 执行以下2条命令解决: apt-get install php-mysql service apache2 restart php -m 执行后会多以下4个模块: mysqli mysqlnd...

SamXIAO ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部