前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用Xpath,bs4,正则三种方式爬51job

用Xpath,bs4,正则三种方式爬51job

作者头像
龙哥
发布2018-10-22 14:16:41
8640
发布2018-10-22 14:16:41
举报
文章被收录于专栏:Python绿色通道

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

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

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

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

注意代码是Py2.7环境

代码语言: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%2C0&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 '\n\n出现错误,错误信息是:{}\n\n'.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 '\n\n出现错误,错误信息是:{}\n\n'.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)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-03-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python绿色通道 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Execl操作工具类:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档