scrapy框架爬取Boss直聘,数据存入mysql

版权声明:大家一起学习,欢迎转载,转载请注明出处。若有问题,欢迎纠正! https://blog.csdn.net/memory_qianxiao/article/details/88416817

自从上次用了scrapy爬取豆瓣电影后,发现scrapy除了入门相对request较难外,各方面都挺好的,速度很快,还有各个功能模块,以及django类似的各种中间件组成一个完善的系统框架,需要一点一点的学习,了解,毕竟官方文档写的太随性了~~~

这次我爬取的是boss直聘上的各种职业,以及该职位的薪水,地点,公司等情况....

老规矩镇楼图如下:

 一张表大概有300个数据,因为boss直聘搜索的条件,只会显示10页,每页大概30条的样子。

接下来进入正题:按照框架的流程走一波~

一:开始一个爬虫项目:scrapy startproject +项目名

eg:scrapy startproject boss_job

会自动生成目录如下:

二:创建spider爬虫 scrapy genspider +爬虫名 +爬取域名

eg:scrapy genspider boss zhipin.com 创建完成后,spider目录下自动生成boss的spider

三:在setting里面把遵守爬虫协议改为不遵守

ROBOTSTXT_OBEY = True 改为-》ROBOTSTXT_OBEY = False

取消DEFAULT_REQUEST_HEADERS 注释,加入自己的浏览器user-agent信息伪装浏览器。

你的user-agent浏览器按F12,选择network,随便选中一个boss直聘中的一个文件,复制其中的user-agent

 四:打开items.py文件,在BossJobItem定义item容器,方便数据的存储,以及数数据的表的建立(和django中的module类似)

代码如下:

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class BossJobItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    company_name=scrapy.Field()#公司名字
    company_locale = scrapy.Field()  # 所在城市
    job_name=scrapy.Field()#工作名称
    job_salary=scrapy.Field()#薪水
    experience_demand=scrapy.Field()#工作经验需求
    educational_demand=scrapy.Field()#学历需求
    company_work=scrapy.Field()#公司种类
    finance=scrapy.Field()#融资
    persons_in_company=scrapy.Field()#公司人数
    crawl_time=scrapy.Field()#爬取时间


五:把boss中的spider编写完成

提取方法是用的是框架自带的xpath,很方便的,还有css,re,等也可以用,提取过程可以在scrapy shell测试,测试完成后就能保证提取的准确性。如果不知道xpath提取,可以看如下菜鸟教程:

菜鸟教程xpath教程:http://www.runoob.com/xpath/xpath-tutorial.html

代码如下:

# -*- coding: utf-8 -*-
import scrapy,time
from ..items import *
class BossSpider(scrapy.Spider):
    name = 'boss'
    allowed_domains = ['zhipin.com']
    key_word=input("请输入需要查询的关键字(python,java,酒店管理,销售,或者职业部分相关关键字):")
    if key_word:
        url='https://www.zhipin.com/c100010000/?query='+key_word
        start_urls = [url]
    else:print("不能为空")


    def parse(self, response):
        item=BossJobItem()#导入item容器
        job_list=response.xpath('//div[@class="job-list"]//ul//li')#所有工作标签列表
        for job in job_list:
            item['company_name']=job.xpath('.//div[@class="info-company"]//h3/a/text()').extract_first()#公司名字
            item['company_locale']=job.xpath('.//div[@class="info-primary"]//p/text()').extract_first()# 所在城市
            item['job_name']=job.xpath('.//div[@class="job-title"]/text()').extract_first()#工作名称
            item['job_salary']=job.xpath('.//div[@class="info-primary"]//span/text()').extract_first()#薪水
            item['experience_demand']=job.xpath('.//div[@class="info-primary"]//p/text()').extract()[1]#工作经验需求
            item['educational_demand']=job.xpath('.//div[@class="info-primary"]//p/text()').extract()[2]#学历需求
            #因为有部分公司,没有融资说明,所以数据会空缺,程序会中断,特判处理
            if len(job.xpath('.//div[@class="info-company"]//p/text()').extract())==3:
                item['company_work']=job.xpath('.//div[@class="info-company"]//p/text()').extract_first()#公司种类
                item['finance']=job.xpath('.//div[@class="info-company"]//p/text()').extract()[1]#融资
                item['persons_in_company']=job.xpath('.//div[@class="info-company"]//p/text()').extract()[2]#公司人数
            else:
                item['company_work'] = job.xpath('.//div[@class="info-company"]//p/text()').extract_first()  # 公司种类
                item['persons_in_company'] = job.xpath('.//div[@class="info-company"]//p/text()').extract()[1]  # 公司人数
            item['crawl_time']=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())#爬取时间

            yield item

        next_url=response.xpath('//div[@class="page"]//a[@ka="page-next"]/@href').extract_first()#提取翻页连接
        print("*" * 120)
        print(self.url + next_url)
        if next_url!="javascript:;":#如果不是最后一页,就回调parse函数,继续爬取
            yield scrapy.Request(self.url+next_url,callback=self.parse)


六:创建数据库,编写pipelines对数据进行清洗入mysql库,以及顺便输出一份json格式的文件

需要安装pymysql库,__init__函数,process_item,close_spider分别表示在爬虫运行开始之前,爬虫运行过程中,关闭爬虫后需要执行的功能,把代码写进你需要在哪个阶段执行对应的函数里面就ok了。我这里需要在运行之前连接数据库,同时判断当前输入的职位关键字,有没有,有了就删除了,重新建,没有就自动建表,同时以二进制方式打开写入json格式的数据文件,运行之中需要把数据传入item 的同时把数据存入myql,需要会插入的mysql语句,也把数据保存为json文件,别忘了,mysql游标记得commit一下保存,否则不会存入数据库。最后关掉文件和数据库连接。

对python操作mysql增删改差不太熟悉的朋友请点击传送门:https://blog.csdn.net/memory_qianxiao/article/details/82620079

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
from scrapy.exporters import JsonLinesItemExporter
from boss直聘.boss_job.boss_job.spiders.boss import BossSpider
import pymysql
#保存json个格式
class BossJobPipeline(object):

    def __init__(self):
        #连接数据库
        dbparams={
            'host':'127.0.0.1',
            'port':3306,
            'user':'test',
            'password':'123',
            'database':'boss直聘',
            'charset':'utf8',
        }
        self.conn=pymysql.connect(**dbparams)
        self.cursor=self.conn.cursor()#获取游标
        self.sql=None

        self.fjson=open('boss.json',"wb")#保存json格式
        self.exporter=JsonLinesItemExporter(self.fjson,ensure_ascii=False)

        # # 创建表之前看是否存在当前要创建的表,有就删除
        self.cursor.execute("drop table if exists %s" % BossSpider.key_word)
        # 创建搜索关键字表sql语句
        sql = """create table %s(
                id  int primary key auto_increment,
                公司名字 varchar (255),
                所在城市 varchar (255),
                工作名称 varchar (255),
                薪水 varchar (255),
                工作经验 varchar (255),
                学历 varchar (255),
                公司种类 varchar (255),
                融资 varchar (255),
                公司人数 varchar (255),
                爬取时间 datetime)"""
        # 执行创建表的语句
        self.cursor.execute(sql % BossSpider.key_word)

    def process_item(self, item, spider):

        #插入数据的sql语句
        self.sql="insert into %s"%BossSpider.key_word+"(公司名字,所在城市,工作名称,薪水,工作经验,学历,公司种类,融资,公司人数,爬取时间) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
        self.cursor.execute(self.sql,(item['company_name'],item['company_locale'],item['job_name'],
                                      item['job_salary'],item['experience_demand'],item['educational_demand'],
                                      item['company_work'],item['finance'],item['persons_in_company'],item['crawl_time']))
        self.conn.commit()#保存数据

        self.exporter.export_item(item)#传入item保存json数据
        return item

    def close_spider(self,spider):
        self.fjson.close()#关闭json文件
        self.conn.close()#关闭数据库连接

七:编写完后pipelines需要在setting 里面把ITEM_PIPELINES注释取消,才能生效

八:运行boss爬虫 scrapy crawl +爬虫名  eg:scrapy crawl boss  

因为会多次爬取或者调试代码,每次运行爬虫,都要手动输入scrapy crawl +名字    这里选择新建一个start.py文件,把运行的语句scrapy crawl boss写进去,每次就不用输入这些代码了,直接鼠标右键运行就可以运行爬虫了。

代码如下:因为执行必须是一个列表的,输入的字符串需要切割(split一下)

# -*- coding: utf-8 -*-
# @Filename: start.py
# @Time    : 2019/3/9 18:14
# @Author  : LYT
from scrapy import cmdline
cmdline.execute('scrapy crawl boss'.split())

运行如下:

最后查看数据库如下:爬取很成功.!

猜你喜欢

转载自blog.csdn.net/memory_qianxiao/article/details/88416817