python爬蟲實戰(zhàn)(1) -- 抓取boss直聘招聘信息

系列文章
python爬蟲實戰(zhàn)(1) -- 抓取boss直聘招聘信息
python爬蟲實戰(zhàn)(2) -- MongoDB和數(shù)據(jù)清洗
python爬蟲實戰(zhàn)(3) -- 數(shù)據(jù)可視化

實驗內(nèi)容:爬取boss直聘的崗位信息茫孔,存儲在數(shù)據(jù)庫,最后通過可視化展示出來

參考:jtahstu https://segmentfault.com/a/1190000012390223

0 環(huán)境搭建

  • MacBook Air (13-inch, 2017)
  • CPU:1.8 GHz Intel Core i5
  • RAM:8 GB 1600 MHz DDR3
  • IDE:anaconda3.6 | jupyter notebook
  • Python版本:Python 3.6.5 :: Anaconda, Inc.

1 安裝scrapy

過程在參考鏈接中汉规,我只說與上面不一致的地方

pip install scrapy
  • 遇到報錯卑吭,無法調(diào)用gcc
    *解決方案:mac自動彈出安裝gcc提示框敷硅,點擊“安裝”即可
  • 安裝成功嗦枢,安裝過程中木羹,終端打印出“distributed 1.21.8 requires msgpack, which is not installed.”
    • 解決方案:
conda install -c anaconda msgpack-python
pip install msgpack

參考:https://stackoverflow.com/questions/51050257/distributed-1-21-8-requires-msgpack-which-is-not-installed

2 新建項目

scrapy startproject www_zhipin_com
可以通過 scrapy -h 了解功能
源碼文件關(guān)系

tree這個命令挺好用翻具,微軟cmd中自帶悼嫉,Python沒有自帶的艇潭,可以參考網(wǎng)上代碼,自己寫一個玩玩戏蔑。

3 定義要抓取的item

與源代碼基本一致

# -*- 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 WwwZhipinComItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    pid = scrapy.Field()
    positionName = scrapy.Field()
    positionLables = scrapy.Field()
    city = scrapy.Field()
    experience = scrapy.Field()
    educational = scrapy.Field()
    salary = scrapy.Field()
    company = scrapy.Field()
    industryField = scrapy.Field()
    financeStage = scrapy.Field()
    companySize = scrapy.Field()
    time = scrapy.Field()
    updated_at = scrapy.Field()

4 分析頁面

現(xiàn)在頁面改版了蹋凝,發(fā)布時間有了小幅度調(diào)整


頁面
HTML結(jié)構(gòu)如下

5 爬蟲代碼

這一步有些看不懂,硬著頭皮往下寫总棵,不懂得先記著

5.1關(guān)于request headers

比如headers中鳍寂,我在自己的瀏覽器中找不到下面內(nèi)容
x-devtools-emulate-network-conditions-client-id ?情龄?
postman-token 迄汛??

參考有x-devtools的網(wǎng)頁
https://bbs.csdn.net/topics/390893160
http://www.cnblogs.com/iloverain/p/9198217.html

我該學(xué)習(xí)一下request headers中內(nèi)容
目前采用的方法是把作者的headers拷貝過去骤视,然后我這邊有的我替換掉鞍爱,沒有的比如x-devtools我就用作者原有的。

5.2 關(guān)于extract_first()和extract()

scrapy實戰(zhàn)還是蠻多的
看到有個爬取豆瓣內(nèi)容的 http://www.reibang.com/p/f36460267ac2

extract_first()和extract()的區(qū)別:
提取全部內(nèi)容: .extract()专酗,獲得是一個列表
提取第一個:.extract_first()睹逃,獲得是一個字符串

Selectors根據(jù)CSS表達式從網(wǎng)頁中選擇數(shù)據(jù)(CSS更常用)
response.selector.css('title::text') ##用css選取了title的文字內(nèi)容
由于selector.css使用比較普遍,所以專門定義了css笼裳,所以上面也可以寫成:
response.css('title::text')

看到有個運維學(xué)python的唯卖,使用py3.6,寫的很實戰(zhàn)躬柬,mark
運維學(xué)python之爬蟲高級篇(五)scrapy爬取豆瓣電影TOP250
運維學(xué)python之爬蟲高級篇(四)Item Pipeline介紹(附爬取網(wǎng)站獲取圖片到本地代碼)
運維學(xué)python之爬蟲高級篇(三)spider和items介紹
運維學(xué)python之爬蟲高級篇(二)用Scrapy框架實現(xiàn)簡單爬蟲
運維學(xué)python之爬蟲高級篇(一)Scrapy框架入門
運維學(xué)python之爬蟲中級篇(九)Python3 MySQL 數(shù)據(jù)庫連接
運維學(xué)python之爬蟲中級篇(八)MongoDB
運維學(xué)python之爬蟲中級篇(七)Sqlite3
運維學(xué)python之爬蟲中級篇(六)基礎(chǔ)爬蟲
運維學(xué)python之爬蟲中級篇(五)數(shù)據(jù)存儲(無數(shù)據(jù)庫版)
運維學(xué)python之爬蟲中級篇(四)網(wǎng)絡(luò)編程
運維學(xué)python之爬蟲中級篇(三)分布式進程
運維學(xué)python之爬蟲中級篇(二)線程拜轨、協(xié)程
運維學(xué)python之爬蟲中級篇(一)進程
運維學(xué)python之爬蟲工具篇(六)Pyquery的用法
運維學(xué)python之爬蟲工具篇(五)Selenium的用法
運維學(xué)python之爬蟲工具篇(四)PhantomJS的用法
運維學(xué)python之爬蟲工具篇(三)Xpath語法與lxml庫的用法
運維學(xué)python之爬蟲工具篇(二)Beautiful Soup的用法
運維學(xué)python之爬蟲工具篇(一)Requests庫的用法
運維學(xué)python之爬蟲基礎(chǔ)篇實戰(zhàn)(七)爬取伯樂在線面向?qū)ο髨D片
運維學(xué)python之爬蟲基礎(chǔ)篇實戰(zhàn)(六)爬取百度貼吧
運維學(xué)python之爬蟲基礎(chǔ)篇(五)正則表達式
運維學(xué)python之爬蟲基礎(chǔ)篇(四)Cookie
運維學(xué)python之爬蟲基礎(chǔ)篇(三)urllib模塊高級用法
運維學(xué)python之爬蟲基礎(chǔ)篇(二)urllib模塊使用
運維學(xué)python之爬蟲基礎(chǔ)篇(一)開篇

運行腳本,會在項目目錄下生成一個包含爬取數(shù)據(jù)的item.json文件
scrapy crawl zhipin -o item.json

debug完最后一個錯誤之后允青,第五步終于跑通了橄碾,截個圖


爬取boss直聘上面關(guān)于python的職位

存入json文件的模樣有點奇怪,沒漢字颠锉,第六步應(yīng)該會解決:

{"pid": "23056497", "positionName": "", "salary": "8k-9k", "city": "\u5317\u4eac", "experience": "\u4e0d\u9650", "educational": "\u672c\u79d1", "company": "\u4eca\u65e5\u5934\u6761", "positionLables": [], "time": "\u53d1\u5e03\u4e8e07\u670812\u65e5", "updated_at": "2018-07-17 00:04:05"},
{"pid": "23066797", "positionName": "", "salary": "18k-25k", "city": "\u5317\u4eac", "experience": "1-3\u5e74", "educational": "\u672c\u79d1", "company": "\u5929\u4e0b\u79c0", "positionLables": [], "time": "\u53d1\u5e03\u4e8e07\u670813\u65e5", "updated_at": "2018-07-17 00:04:05"},

第五步因為網(wǎng)頁發(fā)生改版法牲,所以發(fā)布時間time這塊需要修改一下,其他都沒有問題琼掠。
我也把源碼貼一下:

# 2018-07-17 
# Author limingxuan 
# limx2011@hotmail.com
# blog:http://www.reibang.com/p/a5907362ba72

import scrapy
import time
from www_zhipin_com.items import WwwZhipinComItem

class ZhipinSpider(scrapy.Spider):
    name = 'zhipin'
    allowed_domains = ['www.zhipin.com']
    start_urls = ['http://www.zhipin.com/']
    positionUrl = 'https://www.zhipin.com/job_detail/?query=python&scity=101010100'
    curPage = 1
    #我的瀏覽器找不到源碼中的一些字段拒垃,比如
    #x-devtools-emulate-network-conditions-client-id
    #upgrade-insecure-requests
    #dnt
    #cache-control
    #postman-token
    #所以就沒有加,按我的瀏覽器查到的信息填寫的瓷蛙,現(xiàn)在看起來貌似也能跑起來
    headers = {    
    'accept': "application/json, text/javascript, */*; q=0.01",
    'accept-encoding': "gzip, deflate, br",
    'accept-language': "zh-CN,zh;q=0.9,en;q=0.8",
    'content-type': "application/x-www-form-urlencoded; charset=UTF-8",
    'cookie': "JSESSIONID=""; __c=1530137184; sid=sem_pz_bdpc_dasou_title; __g=sem_pz_bdpc_dasou_title; __l=r=https%3A%2F%2Fwww.zhipin.com%2Fgongsi%2F5189f3fadb73e42f1HN40t8~.html&l=%2Fwww.zhipin.com%2Fgongsir%2F5189f3fadb73e42f1HN40t8~.html%3Fka%3Dcompany-jobs&g=%2Fwww.zhipin.com%2F%3Fsid%3Dsem_pz_bdpc_dasou_title; Hm_lvt_194df3105ad7148dcf2b98a91b5e727a=1531150234,1531231870,1531573701,1531741316; lastCity=101010100; toUrl=https%3A%2F%2Fwww.zhipin.com%2Fjob_detail%2F%3Fquery%3Dpython%26scity%3D101010100; Hm_lpvt_194df3105ad7148dcf2b98a91b5e727a=1531743361; __a=26651524.1530136298.1530136298.1530137184.286.2.285.199",
    'origin': "https://www.zhipin.com",
    'referer': "https://www.zhipin.com/job_detail/?query=python&scity=101010100",
    'user-agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
    }
    
    def start_requests(self):
        return [self.next_request()]
    
    def parse(self,response):
        print("request -> " + response.url)
        job_list = response.css('div.job-list > ul > li')
        for job in job_list:
            item = WwwZhipinComItem()
            job_primary = job.css('div.job-primary')
            item['pid'] = job.css(
                'div.info-primary > h3 > a::attr(data-jobid)').extract_first().strip()
            
            #job-title這里和源碼不同悼瓮,頁面改版所導(dǎo)致
            item['positionName'] = job_primary.css(
                'div.info-primary > h3 > a > div.job-title::text').extract_first().strip()
            item['salary'] = job_primary.css(
                'div.info-primary > h3 > a > span::text').extract_first().strip()
            #提取全部內(nèi)容: .extract()戈毒,獲得是一個列表
            #提取第一個:.extract_first(),獲得是一個字符串
            info_primary = job_primary.css(
                'div.info-primary > p::text').extract()
            item['city'] = info_primary[0].strip()
            item['experience'] = info_primary[1].strip()
            item['educational'] = info_primary[2].strip()
            item['company'] = job_primary.css(
                'div.info-company > div.company-text > h3 > a::text').extract_first().strip()
            company_infos = job_primary.css(
                'div.info-company > div.company-text > p::text').extract()
            if len(company_infos)== 3:
                item['industryField'] = company_infos[0].strip()
                item['financeStage'] = company_infos[1].strip()
                item['companySize'] = company_infos[2].strip()
            
            #頁面改版横堡,已沒有標簽埋市,所以這一段代碼    
            item['positionLables'] = job.css(
                'li > div.job-tags > span::text').extract()
            
            #Python strip() 方法用于移除字符串頭尾指定的字符(默認為空格)或字符序列。
            #注意:該方法只能刪除開頭或是結(jié)尾的字符命贴,不能刪除中間部分的字符道宅。
            #此處頁面已改版,和源代碼不同
            item['time'] = job_primary.css(
                'div.info-publis > p::text').extract_first().strip()
            
            item['updated_at'] = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
            yield item
            
        self.curPage += 1
        time.sleep(5) #爬的慢一點胸蛛,免得被封ip
        yield self.next_request()
        
    def next_request(self):
        return scrapy.http.FormRequest(
            self.positionUrl + ("&page=%d&ka=page-%d" % 
                               (self.curPage, self.curPage)),
            headers=self.headers,
            callback=self.parse)

5.3 json數(shù)據(jù)漢化

還記得之前貼出來的item.json文件嗎污茵,全是英文和字符,按照這一步胚泌,重新爬取省咨,將轉(zhuǎn)換成漢字

Point 1 設(shè)置 UTF-8 編碼
但是不巧肃弟,往往這是一個 Unicode 編碼的文件玷室,所以需要加個設(shè)置
在 settings.py中添加(PS:也可以在運行的時候帶上這個參數(shù))

FEED_EXPORT_ENCODING = 'utf-8'

重新爬取后

{"pid": "23200059", "positionName": "高級后端工程師(Python)", "salary": "20k-40k", "city": "北京", "experience": "3-5年", "educational": "本科", "company": "Kavout", "positionLables": [], "time": "發(fā)布于昨天", "updated_at": "2018-07-17 12:43:14"},
{"pid": "23199912", "positionName": "Python開發(fā)工程師", "salary": "12k-16k", "city": "北京", "experience": "3-5年", "educational": "本科", "company": "北京南天", "positionLables": [], "time": "發(fā)布于昨天", "updated_at": "2018-07-17 12:43:14"},

預(yù)告

下一篇,python爬蟲實戰(zhàn)(2) -- MongoDB和數(shù)據(jù)清洗

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末笤受,一起剝皮案震驚了整個濱河市穷缤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌箩兽,老刑警劉巖津肛,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異汗贫,居然都是意外死亡身坐,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門落包,熙熙樓的掌柜王于貴愁眉苦臉地迎上來部蛇,“玉大人,你說我怎么就攤上這事咐蝇⊙穆常” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵有序,是天一觀的道長抹腿。 經(jīng)常有香客問我,道長旭寿,這世上最難降的妖魔是什么警绩? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮盅称,結(jié)果婚禮上肩祥,老公的妹妹穿的比我還像新娘僚匆。我一直安慰自己,他們只是感情好搭幻,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布咧擂。 她就那樣靜靜地躺著,像睡著了一般檀蹋。 火紅的嫁衣襯著肌膚如雪松申。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天俯逾,我揣著相機與錄音贸桶,去河邊找鬼。 笑死桌肴,一個胖子當著我的面吹牛皇筛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播坠七,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼水醋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了彪置?” 一聲冷哼從身側(cè)響起拄踪,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拳魁,沒想到半個月后惶桐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡潘懊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年姚糊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片授舟。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡救恨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出岂却,到底是詐尸還是另有隱情忿薇,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布躏哩,位于F島的核電站署浩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏扫尺。R本人自食惡果不足惜筋栋,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望正驻。 院中可真熱鬧弊攘,春花似錦抢腐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至捣域,卻和暖如春啼染,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背焕梅。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工迹鹅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贞言。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓斜棚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親该窗。 傳聞我的和親對象是個殘疾皇子弟蚀,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

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