通俗易懂的分析如何用Python实现一只小爬虫,爬取拉勾网的职位信息

源代码:https://github.com/nnngu/LagouSpider


效果预览

思路

1、首先我们打开拉勾网,并搜索“java”,显示出来的职位信息就是我们的目标。

2、接下来我们需要确定,怎样将信息提取出来。

  • 查看网页源代码,这时候发现,网页源代码里面找不到职位相关信息,这证明拉勾网关于职位的信息是异步加载的,这也是一种很常用的技术。

  • 异步加载的信息,我们需要借助 chrome 浏览器的开发者工具进行分析,打开开发者工具的方法如下:

  • 点击Nerwork进入网络分析界面,这时候是一片空白,刷新一下界面就可以看到一系列的网络请求了。
  • 前面我们说到,拉勾网关于职位的信息是异步加载的,那么在这一系列的网络请求中,必定有某个请求发送给服务器,响应回来的是职位信息。

  • 正常情况下,我们可以忽略css,图片等类型的请求,关注点放在XHR这种类型请求上,如图:

一共4个XHR类型的请求,我们逐个打开对比,分别点击Preview就能看到它们响应的内容。

发现第一个请求就是我们要找的。如图:

点击Headers,查看一下请求参数。如下图:

到此,我们可以确定city参数就是城市,pn参数就是页数,kd参数就是搜索关键字。

接下来开始写代码了。

代码

代码分成四个部分,便于后期维护。

1、基本 https 请求https.py

这部分对 requests 包进行了一些封装,部分代码如下:

# -*- coding: utf-8 -*-
from src.setting import IP, UA
import requests, random
import logging


class Http:
    '''
    http请求相关的操作
    '''

    def __init__(self):
        pass

    def get(self, url, headers=None, cookies=None, proxy=None, timeOut=5, timeOutRetry=5):
        '''
        获取网页源码
        url: 网页链接
        headers: headers
        cookies: cookies
        proxy: 代理
        timeOut: 请求超时时间
        timeOutRetry: 超时重试次数
        return: 源码
        '''
        if not url:
            logging.error('GetError url not exit')
            return 'None'
            
        # 这里只展示了一部分代码
        # 完整代码已上传到Github

这里只展示了一部分代码,完整代码已上传到Github

2、代码主逻辑部分main.py

这部分的程序逻辑,如下:

  • 获取职位信息
def getInfo(url, para):
    """
    获取信息
    """
    generalHttp = Http()
    htmlCode = generalHttp.post(url, para=para, headers=headers, cookies=cookies)
    generalParse = Parse(htmlCode)
    pageCount = generalParse.parsePage()
    info = []
    for i in range(1, 3):
        print('第%s页' % i)
        para['pn'] = str(i)
        htmlCode = generalHttp.post(url, para=para, headers=headers, cookies=cookies)
        generalParse = Parse(htmlCode)
        info = info + getInfoDetail(generalParse)
        time.sleep(2)
    return info
  • 对信息进行储存
def processInfo(info, para):
    """
    信息存储
    """
    logging.error('Process start')
    try:
        title = '公司名称\t公司类型\t融资阶段\t标签\t公司规模\t公司所在地\t职位类型\t学历要求\t福利\t薪资\t工作经验\n'
        file = codecs.open('%s职位.xls' % para['city'], 'w', 'utf-8')
        file.write(title)
        for p in info:
            line = str(p['companyName']) + '\t' + str(p['companyType']) + '\t' + str(p['companyStage']) + '\t' + \
                   str(p['companyLabel']) + '\t' + str(p['companySize']) + '\t' + str(p['companyDistrict']) + '\t' + \
                   str(p['positionType']) + '\t' + str(p['positionEducation']) + '\t' + str(
                p['positionAdvantage']) + '\t' + \
                   str(p['positionSalary']) + '\t' + str(p['positionWorkYear']) + '\n'
            file.write(line)
        file.close()
        return True
    except Exception as e:
        print(e)
        return None

3、信息解析部分parse.py

这部分针对服务器返回的职位信息的特点,进行解析,如下:

class Parse:
    '''
    解析网页信息
    '''

    def __init__(self, htmlCode):
        self.htmlCode = htmlCode
        self.json = demjson.decode(htmlCode)
        pass

    def parseTool(self, content):
        '''
        清除html标签
        '''
        if type(content) != str: return content
        sublist = ['<p.*?>', '</p.*?>', '<b.*?>', '</b.*?>', '<div.*?>', '</div.*?>',
                   '</br>', '<br />', '<ul>', '</ul>', '<li>', '</li>', '<strong>',
                   '</strong>', '<table.*?>', '<tr.*?>', '</tr>', '<td.*?>', '</td>',
                   '\r', '\n', '&.*?;', '&', '#.*?;', '<em>', '</em>']
        try:
            for substring in [re.compile(string, re.S) for string in sublist]:
                content = re.sub(substring, "", content).strip()
        except:
            raise Exception('Error ' + str(substring.pattern))
        return content
        
        # 这里只展示了一部分代码
        # 完整代码已上传到Github

这里只展示了一部分代码,完整代码已上传到Github

4、配置部分setting.py

这部分加入 cookies 的原因是为了应对拉勾网的反爬,长期使用需要进行改进,进行动态 cookies 获取

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

# headers
headers = {
    'Host': 'www.lagou.com',
    'Connection': 'keep-alive',
    'Content-Length': '23',
    'Origin': 'https://www.lagou.com',
    'X-Anit-Forge-Code': '0',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
    'Accept': 'application/json, text/javascript, */*; q=0.01',
    'X-Requested-With': 'XMLHttpRequest',
    'X-Anit-Forge-Token': 'None',
    'Referer': 'https://www.lagou.com/jobs/list_java?city=%E5%B9%BF%E5%B7%9E&cl=false&fromSearch=true&labelWords=&suginput=',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7'
}

测试

运行结果:

爬取结束后,在src目录下就可以看到爬虫爬取到的数据。

到此,拉勾网的职位信息抓取就完成了。完整代码已经上传到我的Github

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,401评论 25 707
  • 为了获取拉勾网的招聘信息,对数据分析岗位的基本信息进行爬取。之所以选择拉勾网作为本项目的数据源,主要是因为相对于其...
    YoLean阅读 2,251评论 1 6
  • 文:林清 “现在的我看不到以前的你 也找不到现在的你.” 小时候 孤独是所谓一个人, 没有人和自己聊天 玩耍, 一...
    林苏泽阅读 347评论 0 2
  • 今天晚上和我妈和我弟弟打羽毛球 有点敏感 学会和自己的思维共处 加油!!!
    Onion_Story阅读 71评论 0 0