实战篇 | 用Xpath,bs4,正则三种方式爬51job

2019-10-24 16:05:15 浏览数 (1)

最近整理一个爬虫系列方面的文章,不管大家的基础如何,我从头开始整一个爬虫系列方面的文章,让大家循序渐进的学习爬虫,小白也没有学习障碍.

爬虫篇:使用Python动态爬取某大V微博,再用词云分析

爬虫篇 | 动态爬取QQ说说并生成词云,分析朋友状况

爬虫篇 | 200 行代码实现一个滑动验证码

爬虫篇 | 学习Selenium并使用Selenium模拟登录知乎

爬虫篇 | Python使用正则来爬取豆瓣图书数据

爬虫篇 | 不会这几个库,都不敢说我会Python爬虫

爬虫篇 | Python现学现用xpath爬取豆瓣音乐

爬虫篇 | Python最重要与重用的库Request

爬虫篇 | Python爬虫学前普及

基础篇 | Python基础部分

最近和星球球友一起做了一个爬取51job上的Python招聘职位的项目实战,数据如下:

涉及到的知识点是:xpath,bs4,正则,request,execl,类,函数,以及其它基础知识的综合

下面是我的实现 代码的节选部分. 完整代码围观https://github.com/pythonchannel/fetch_51job

注释都已经很清楚了,没有啥要写的了

代码语言:javascript复制
# coding:utf-8
import time
import abc
import requests
from ExeclUtils import ExeclUtils

'''
这是爬虫的抽象类,
xpath,bs4,re 三种爬虫方式都继承这个类
因为所有的请求列表与详情是通用的,所以我这里把请求数据都放在基类中
然后调用爬取方式,爬取方式在子类中实现

'''


class Spider(object):
    # 定义一个抽象类
    __metaclass__ = abc.ABCMeta

    def __init__(self):
        self.rows_title = [u'招聘标题', u'公司名称', u'公司地址', u'待遇', u'发布日期', u'招聘链接', u'招聘要求描述']
        sheet_name = u'51job_Python招聘'
        return_execl = ExeclUtils.create_execl(sheet_name, self.rows_title)
        self.execl_f = return_execl[0]
        self.sheet_table = return_execl[1]
        self.job_info = []  # 存放每一条数据中的各元素,
        self.count = 0  # 数据插入从1开始的

    def crawler_data(self):
        '''
        开始爬取数据
        :return:
        '''
        for i in range(1, 5):
            url = 'http://search.51job.com/list/000000,000000,0000,00,9,99,python,2,{}.html?lang=c&stype=1&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&lonlat=0,0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare='.format(
                i)
            self.request_job_list(url)
            # 采集不要太快了,否则容易造成ip被封或者网络请求失败
            time.sleep(2)

    def request_job_list(self, page_url):
        '''
        获取工作列表
        :param page_url:
        :return:
        '''
        try:
            headers = {
                'Referer': 'http://www.51job.com/',
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.4549.400 QQBrowser/9.7.12900.400'
            }
            response = requests.get(page_url, headers=headers)
            response.encoding = 'gbk'
            # 如果请求失败,则不能继续进行
            if response.status_code != 200:
                return
            self.parse_job_list(response.text)
        except Exception as e:
            print 'nn出现错误,错误信息是:{}nn'.format(e.message)

    @abc.abstractmethod
    def parse_job_list(self, text):
        '''
        解析工作列表的抽象方法,具体实现在子类中
        :param text:
        :return:
        '''
        pass

    def request_job_detail(self, job_href):
        '''
        获取工作详情
        :param job_href: 招聘工作的链接
        :return:
        '''
        try:
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.4549.400 QQBrowser/9.7.12900.400'
            }
            response = requests.get(job_href, headers=headers)
            response.encoding = 'gbk'
            # 如果请求失败,则不能继续进行
            if response.status_code != 200:
                return ''

            self.parse_job_detail(response.text)

        except Exception as e:
            print 'nn出现错误,错误信息是:{}nn'.format(e.message)

    @abc.abstractmethod
    def parse_job_detail(self, text):
        '''
        定义工作详情的抽象方法
        :param text:
        :return:
        '''
        pass

Execl操作工具类:

代码语言:javascript复制
import xlwt

import sys

reload(sys)
sys.setdefaultencoding('utf-8')

'''
这里是操作execl的工具类,以后也可以直接复用
方法调用SpiderUtils.create_excecl(...)
'''


class ExeclUtils(object):

    @staticmethod
    def create_execl(sheet_name, row_titles):
        '''
        创建execl文件与sheet表,并创建他们的第一行标题
        :param sheet_name: execl中sheet_name文件的名称
        :param row_titles: execl文件的标题行
        :return: execl_file,execl_sheet
        '''

        f = xlwt.Workbook()
        sheet_info = f.add_sheet(sheet_name, cell_overwrite_ok=True)
        for i in range(0, len(row_titles)):
            sheet_info.write(0, i, row_titles[i])

        return f, sheet_info

    @staticmethod
    def write_execl(execl_file, execl_sheet, count, data, execl_name):
        '''
        把数据写入到execl中.这是一个静态方法
        注意:这里所有的数据都不要写死,方便复用.
        :param execl_file:  传入一个execl文件
        :param execl_sheet:  传入一个execl_sheet表
        :param count:  execl文件的行数
        :param data:  要传入的一条数据
        :param execl_name: execl文件名
        :return: None
        '''
        for j in range(len(data)):
            execl_sheet.write(count, j, data[j])

        execl_file.save(execl_name)

如果你觉得文章还不错,请大家点赞分享下。你的肯定是我最大的鼓励和支持。

0 人点赞