通俗易懂的分析如何用Python實現(xiàn)一只小爬蟲,爬取拉勾網(wǎng)的職位信息

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


效果預(yù)覽

思路

1亚兄、首先我們打開拉勾網(wǎng)混稽,并搜索“java”,顯示出來的職位信息就是我們的目標(biāo)。

2匈勋、接下來我們需要確定礼旅,怎樣將信息提取出來。

  • 查看網(wǎng)頁源代碼洽洁,這時候發(fā)現(xiàn)痘系,網(wǎng)頁源代碼里面找不到職位相關(guān)信息,這證明拉勾網(wǎng)關(guān)于職位的信息是異步加載的饿自,這也是一種很常用的技術(shù)汰翠。

  • 異步加載的信息,我們需要借助 chrome 瀏覽器的開發(fā)者工具進(jìn)行分析璃俗,打開開發(fā)者工具的方法如下:

  • 點擊Nerwork進(jìn)入網(wǎng)絡(luò)分析界面奴璃,這時候是一片空白,刷新一下界面就可以看到一系列的網(wǎng)絡(luò)請求了城豁。
  • 前面我們說到苟穆,拉勾網(wǎng)關(guān)于職位的信息是異步加載的,那么在這一系列的網(wǎng)絡(luò)請求中唱星,必定有某個請求發(fā)送給服務(wù)器雳旅,響應(yīng)回來的是職位信息。

  • 正常情況下间聊,我們可以忽略css攒盈,圖片等類型的請求,關(guān)注點放在XHR這種類型請求上哎榴,如圖:

一共4個XHR類型的請求型豁,我們逐個打開對比,分別點擊Preview就能看到它們響應(yīng)的內(nèi)容尚蝌。

發(fā)現(xiàn)第一個請求就是我們要找的迎变。如圖:

點擊Headers,查看一下請求參數(shù)飘言。如下圖:

到此衣形,我們可以確定city參數(shù)就是城市,pn參數(shù)就是頁數(shù)姿鸿,kd參數(shù)就是搜索關(guān)鍵字谆吴。

接下來開始寫代碼了。

代碼

代碼分成四個部分苛预,便于后期維護(hù)句狼。

1、基本 https 請求https.py

這部分對 requests 包進(jìn)行了一些封裝热某,部分代碼如下:

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


class Http:
    '''
    http請求相關(guān)的操作
    '''

    def __init__(self):
        pass

    def get(self, url, headers=None, cookies=None, proxy=None, timeOut=5, timeOutRetry=5):
        '''
        獲取網(wǎng)頁源碼
        url: 網(wǎng)頁鏈接
        headers: headers
        cookies: cookies
        proxy: 代理
        timeOut: 請求超時時間
        timeOutRetry: 超時重試次數(shù)
        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
  • 對信息進(jìn)行儲存
def processInfo(info, para):
    """
    信息存儲
    """
    logging.error('Process start')
    try:
        title = '公司名稱\t公司類型\t融資階段\t標(biāo)簽\t公司規(guī)模\t公司所在地\t職位類型\t學(xué)歷要求\t福利\t薪資\t工作經(jīng)驗\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

這部分針對服務(wù)器返回的職位信息的特點旺隙,進(jìn)行解析,如下:

class Parse:
    '''
    解析網(wǎng)頁信息
    '''

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

    def parseTool(self, content):
        '''
        清除html標(biāo)簽
        '''
        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 的原因是為了應(yīng)對拉勾網(wǎng)的反爬,長期使用需要進(jìn)行改進(jìn)榔袋,進(jìn)行動態(tài) 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'
}

測試

運(yùn)行結(jié)果:

爬取結(jié)束后周拐,在src目錄下就可以看到爬蟲爬取到的數(shù)據(jù)。

到此凰兑,拉勾網(wǎng)的職位信息抓取就完成了妥粟。完整代碼已經(jīng)上傳到我的Github

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吏够,隨后出現(xiàn)的幾起案子勾给,更是在濱河造成了極大的恐慌,老刑警劉巖锅知,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件播急,死亡現(xiàn)場離奇詭異,居然都是意外死亡售睹,警方通過查閱死者的電腦和手機(jī)桩警,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昌妹,“玉大人捶枢,你說我怎么就攤上這事》裳拢” “怎么了烂叔?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蚜厉。 經(jīng)常有香客問我,道長畜眨,這世上最難降的妖魔是什么昼牛? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮康聂,結(jié)果婚禮上贰健,老公的妹妹穿的比我還像新娘。我一直安慰自己恬汁,他們只是感情好伶椿,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般脊另。 火紅的嫁衣襯著肌膚如雪导狡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天偎痛,我揣著相機(jī)與錄音旱捧,去河邊找鬼。 笑死踩麦,一個胖子當(dāng)著我的面吹牛枚赡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谓谦,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼贫橙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了反粥?” 一聲冷哼從身側(cè)響起卢肃,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎星压,沒想到半個月后践剂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡娜膘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年逊脯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片竣贪。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡军洼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出演怎,到底是詐尸還是另有隱情匕争,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布爷耀,位于F島的核電站甘桑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏歹叮。R本人自食惡果不足惜跑杭,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咆耿。 院中可真熱鬧德谅,春花似錦、人聲如沸萨螺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至椭盏,卻和暖如春组砚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背庸汗。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工惫确, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蚯舱。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓改化,卻偏偏與公主長得像,于是被迫代替她去往敵國和親枉昏。 傳聞我的和親對象是個殘疾皇子陈肛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,846評論 25 707
  • 為了獲取拉勾網(wǎng)的招聘信息,對數(shù)據(jù)分析崗位的基本信息進(jìn)行爬取兄裂。之所以選擇拉勾網(wǎng)作為本項目的數(shù)據(jù)源句旱,主要是因為相對于其...
    YoLean閱讀 2,260評論 1 6
  • 文:林清 “現(xiàn)在的我看不到以前的你 也找不到現(xiàn)在的你.” 小時候 孤獨是所謂一個人, 沒有人和自己聊天 玩耍晰奖, 一...
    林蘇澤閱讀 351評論 0 2
  • 今天晚上和我媽和我弟弟打羽毛球 有點敏感 學(xué)會和自己的思維共處 加油L溉觥!匾南!
    Onion_Story閱讀 73評論 0 0