1. 程式人生 > >Scrapy爬取拉勾網職位資訊

Scrapy爬取拉勾網職位資訊

很多網站都用了一種叫做Ajax(非同步載入)的技術,通常我們會發現這種網頁,打開了,先給你看上面一部分東西,然後剩下的東西再慢慢載入,也就是區域性載入。所以你可以看到很多網頁,瀏覽器中的網址沒變,但是資料照樣是可以更新的。這對我們正確爬取資料造成了一定影響,我們必須要分析出正確的目標地址才能成功爬取資訊。

這裡寫圖片描述

一、目標地址

通過上篇檔案的介紹,以上面的目標地址,我們可以很輕鬆搭建一個爬蟲框架。

我的蜘蛛檔案程式碼:

# -*- coding: utf-8 -*-
import scrapy


class PositionSpider(scrapy.Spider):
    name = "position"
# allowed_domains = ["lagou.com/zhaopin/"] start_urls = ['http://lagou.com/zhaopin//'] def parse(self, response): file = open("lagou.html", 'w') file.write(response.body) file.close() print response.body

然後開啟lagou.html檔案,發現頁面有點low啊,沒關係,能看出一些資訊就好。
這裡寫圖片描述

這裡的職位資訊和上面圖片中顯示的職位是一致的,我們就這樣簡單抓取了嗎?是的,其實首頁是可以按照前面的方式抓取,但是這裡不是我們要抓取的資料。我們要抓取特定條件下的職位資訊。

這裡我們首先開啟開發者工具。

這裡寫圖片描述

所以很容易想到這裡是通過javascript的ajax技術傳送的網路請求事件。

在網路面板下我們嘗試在過濾器中輸入json,對請求進行過濾下。
這裡寫圖片描述

我們發現了2個資源感覺特別像,其中有個名字直接有position,我們點選右鍵,在新標籤頁開啟看看。

我們點選open link in new tab。

這裡寫圖片描述

這裡寫圖片描述

gj=應屆畢業生&xl=大專&jd=成長型&hy=移動網際網路&px=new&city=上海

通過修改這些引數,我們就可以獲取不同的職位資訊。

注意:這裡的構造還比較簡單,有時候,有些網址的構造遠比這個複雜,經常會出現一些你不知道什麼意思的id=什麼的,這個時候,可能這個id的可能值可能就在別的檔案中,你可能還得找一遍,也可能就在網頁原始碼中的某個地方。

還有一種情況,可能會出現time=什麼的,這就是時間戳,這時候,需要用time函式構造。總之,要具體情況具體分析。

import time
time.time()

二、編寫爬蟲

1、爬第一頁

我們來看下返回的json資料結構:

這裡寫圖片描述

我們對照這裡的層級關係,編寫解析json資料的程式碼。

首先引入json模組:

import json

蜘蛛檔案程式碼:

# -*- coding: utf-8 -*-
# coding=utf-8
import json

import scrapy


class PositionSpider(scrapy.Spider):
    name = "position"
    # allowed_domains = ["lagou.com/zhaopin/"]
    start_urls = ['https://www.lagou.com/jobs/positionAjax.json?px=new&city=%E6%9D%AD%E5%B7%9E&district=%E8%A5%BF%E6%B9%96%E5%8C%BA&needAddtionalResult=false']

    def parse(self, response):
        # print response.body
        jdict = json.loads(response.body)
        jcontent = jdict["content"]
        jposresult = jcontent["positionResult"]
        jresult = jposresult["result"]
        for each in jresult:
            print each['city']
            print each['companyFullName']
            print each['companySize']
            print each['positionName']
            print each['secondType']
            print each['salary']
            print ''

執行下看看效果:

這裡寫圖片描述

2、爬取更多頁

我們可以爬取第一頁的資料了,接下來再來看這個請求的具體情況:

這裡寫圖片描述

通過瀏覽器的工具提供的資訊可以看出,這是一個表單方式提交引數的post請求。下面我們就要模擬這種請求方式。

重寫Spider的start_requests方法,並使用FormRequest設定post請求,並且我們可以修改xrang的範圍,下載指定範圍內頁面的資料。程式碼如下:

# -*- coding: utf-8 -*-
import json

import scrapy


class PositionSpider(scrapy.Spider):
    name = "position"
    # allowed_domains = ["lagou.com/zhaopin/"]
    start_urls = [
        'https://www.lagou.com/jobs/positionAjax.json?px=new&city=%E6%9D%AD%E5%B7%9E&district=%E8%A5%BF%E6%B9%96%E5%8C%BA&needAddtionalResult=false']

    city = u'杭州'

    district = u'西湖區'

    url = 'https://www.lagou.com/jobs/positionAjax.json'

    def start_requests(self):
        for num in xrange(1, 5):
            form_data = {'pn': str(num), 'city': self.city, 'district': self.district}
            headers = {
                'Host': 'www.jycinema.com',
                'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
            }
            yield scrapy.FormRequest(self.url, formdata=form_data, callback=self.parse)
        # requests = []
        # for num in xrange(1, 5):
        #     requests.append(scrapy.FormRequest(self.url, method='post', formdata={'pn': str(num), 'city': self.city,'district':self.district},  callback=self.parse))
        # return requests

    def parse(self, response):
        # print response.body
        jdict = json.loads(response.body)
        jcontent = jdict["content"]
        jposresult = jcontent["positionResult"]
        jresult = jposresult["result"]

        for each in jresult:
            print each['city']
            print each['companyFullName']
            print each['companySize']
            print each['positionName']
            print each['secondType']
            print each['salary']
            print ''

執行程式我們可以成功的抓取1-4頁的所有職位資訊。

這裡不提供資料的截圖了,因為這裡資料是經常變化的。如果你自己去測試一下,肯定和我的資料是不一樣的。

3、自動翻頁

# -*- coding: utf-8 -*-
# coding=utf-8
import json

import scrapy


class PositionSpider(scrapy.Spider):
    name = "position"
    # allowed_domains = ["lagou.com/zhaopin/"]
    start_urls = [
        'https://www.lagou.com/jobs/positionAjax.json']

    totalPageCount = 0
    curpage = 1

    city = u'杭州'

    district = u'西湖區'

    url = 'https://www.lagou.com/jobs/positionAjax.json'

    # 設定下載延時
    # download_delay = 10

    def start_requests(self):
        # for num in xrange(1, 3):
        #     form_data = {'pn': str(num), 'city': self.city, 'district': self.district}
        #     headers = {
        #         'Host': 'www.jycinema.com',
        #         'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
        #         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
        #     }
        #     yield scrapy.FormRequest(self.url, formdata=form_data, callback=self.parse)
        # requests = []
        # for num in xrange(1, 5):
        #     requests.append(scrapy.FormRequest(self.url, method='post', formdata={'pn': str(num), 'city': self.city,'district':self.district},  callback=self.parse))
        # return requests
        return [scrapy.FormRequest(self.url,formdata={'pn': str(self.curpage), 'city': self.city,'district':self.district},
                                   callback=self.parse)]

    def parse(self, response):
        # print response.body
        # print response.body.decode('utf-8')
        print str(self.curpage) + "page"
        jdict = json.loads(response.body)
        jcontent = jdict['content']
        jposresult = jcontent["positionResult"]
        pageSize = jcontent["pageSize"]
        jresult = jposresult["result"]
        self.totalPageCount = jposresult['totalCount'] / pageSize + 1;
        for each in jresult:
            print each['city']
            print each['companyFullName']
            print each['companySize']
            print each['positionName']
            print each['secondType']
            print each['salary']
            print ''
        if self.curpage <= self.totalPageCount:
            self.curpage += 1
            yield scrapy.http.FormRequest(self.url, formdata={'pn': str(self.curpage), 'city': self.city,'district': self.district},
                                          callback=self.parse)

最後如果要儲存資料,請參考上篇文章。

這裡針對反爬蟲也做了一點策略,例如使用USER AGENT池,通過下面方式可以檢視請求所使用的user agent。

這裡寫圖片描述

當shell載入後,您將得到一個包含response資料的本地 response 變數以及request變數。輸入 response.body 將輸出response的包體, 輸出 request.headers 可以看到request的包頭。

這裡寫圖片描述

應對反爬蟲策略:

  • 設定download_delay
  • 禁止cookies
  • 使用user agent池
  • 使用IP池
  • 分散式爬取

此工程原始碼已上傳github, 點此檢視

相關推薦

Scrapy職位資訊

很多網站都用了一種叫做Ajax(非同步載入)的技術,通常我們會發現這種網頁,打開了,先給你看上面一部分東西,然後剩下的東西再慢慢載入,也就是區域性載入。所以你可以看到很多網頁,瀏覽器中的網址沒變,但是資料照樣是可以更新的。這對我們正確爬取資料造成了一定影響,我們

【圖文詳解】scrapy爬蟲與動態頁面——職位資訊(1)

5-14更新 注意:目前拉勾網換了json結構,之前是content - result 現在改成了content- positionResult - result,所以大家寫程式碼的時候要特別注意加上

【圖文詳解】scrapy爬蟲與動態頁面——職位資訊(2)

上次挖了一個坑,今天終於填上了,還記得之前我們做的拉勾爬蟲嗎?那時我們實現了一頁的爬取,今天讓我們再接再厲,實現多頁爬取,順便實現職位和公司的關鍵詞搜尋功能。 之前的內容就不再介紹了,不熟悉的請一定要去看之前的文章,程式碼是在之前的基礎上修改的

scrapy職位資訊(一)——scrapy初識及lagou爬蟲專案建立

本次以scrapy抓取拉勾網職位資訊作為scrapy學習的一個實戰演練 python版本:3.7.1 框架:scrapy(pip直接安裝可能會報錯,如果是vc++環境不滿足,建議直接安裝一個visual studio一勞永逸,如果報錯缺少前置依賴,就先安裝依賴)     本篇

scrapy職位資訊(四)——對欄位進行提取

上一篇中已經分析了詳情頁的url規則,並且對items.py檔案進行了編寫,定義了我們需要提取的欄位,本篇將具體的items欄位提取出來 這裡主要是涉及到選擇器的一些用法,如果不是很熟,可以參考:scrapy選擇器的使用   依舊是在lagou_c.py檔案中編寫程式碼 首先是匯入Lag

Python scrapy 招聘資訊

週末折騰了好久,終於成功把拉鉤網的招聘資訊爬取下來了。現在總結一下! 環境: windows 8.1 + python 3.5.0 首先使用 scrapy 建立一個專案: E:\mypy> scrapy startproject lgjob 建立後目錄結構:

Python 爬蟲-模擬登入知乎-職位資訊

用Python寫爬蟲是很方便的,最近看了xlzd.me的文章,他的文章寫的很到位,提供了很好的思路。因為他的文章部分程式碼省略了。下面是基於他的文章的三個程式碼片段: 基於Python3,Python2的話需要修改下input輸入函式和print的用法。 爬取豆瓣電影top250 爬取拉勾網職位資訊 模擬

scrapypython職位+Mysql+視覺化

在進行爬取目標網站中為遇到一個問題,爬取5頁資料之後會出錯,設定了每一次請求的隨機超時間10-20->time.sleep(random.randint(10, 20)),同樣會被拉勾網禁止請求資料,可能被輕度判定為爬取,所以可以設定每一次的隨機超時間為20-30秒,就可以解決這個問題。

用python招聘資訊並以CSV檔案儲存

爬取拉勾網招聘資訊 1、在網頁原始碼中搜索資訊,並沒有搜到,判斷網頁資訊使用Ajax來實現的 2、檢視網頁中所需的資料資訊,返回的是JSON資料; 3、條件為北京+資料分析師的公司一共40087家,而實際拉勾網展示的資料只有 15條/頁 * 30頁 = 450條,所以需要判斷

HttpClient招聘資訊

1.匯入jar包 <dependency>       <groupId>org.apache.httpcomponents</groupId>       <artifactId>htt

scrapy職位信息(一)——scrapy初識及lagou爬蟲項目建立

報錯 中間鍵 方式 set 分享圖片 生成 pytho 薪酬 color 本次以scrapy抓取拉勾網職位信息作為scrapy學習的一個實戰演練 python版本:3.7.1 框架:scrapy(pip直接安裝可能會報錯,如果是vc++環境不滿足,建議直接安裝一個visua

Python招聘資訊存入資料庫

先抓包分析我們想要獲取的資料,很明顯都是動態資料,所以直接到Network下的XHR裡去找,這裡我們找到具體資料後,就要去尋分析求地址與請求資訊了。還有需要提交的表單資訊分析完畢之後,我們就可以開始寫我們的爬蟲專案了。一.編寫Itemitem編寫比較簡單# 拉鉤職位資訊 cl

Python招聘資訊

此程式碼執行建議Python3,省卻中文編碼的麻煩 遇到的幾個問題: (1)拉鉤網的資料是通過js的ajax動態生成,所以不能直接爬取,而是通過post’http://www.lagou.com/jobs/positionAjax.json?needAddt

Python招聘資訊並可視化分析

需求: 1:獲取指定崗位的招聘資訊 2:對公司地區,公司待遇,學歷情況,工作經驗進行簡單分析並可視化展示 視覺化分析: 公司地區:柱狀圖,地圖 公司待遇:雲圖 公司-學歷情況:餅圖 公司工作經

python爬蟲: 職位並分析

0. 前言 本文從拉勾網爬取深圳市資料分析的職位資訊,並以CSV格式儲存至電腦, 之後進行資料清洗, 生成詞雲,進行描述統計和迴歸分析,最終得出結論. 1. 用到的軟體包 Python版本: Python3.6 requests: 下載網

【爬蟲相關】爬蟲的安卓招聘資訊

我爬取了30頁拉勾上安卓的招聘資料告訴你 安卓崗位究竟要一個什麼樣的人 我知道沒圖你們是不會看的 如圖:以上是抓取了30頁拉勾上關於招聘安卓相關的內容 然後根據詞頻 製作出詞雲圖  出現最多的詞是 開發經驗 整體流程總共分為2步 1.爬蟲爬取相關的招聘資訊 2.根

資訊,翻頁

import requests #這個庫等價於 urllib 和urllib2 import bs4 #作用是用來解析網頁的 import json#主要是一種資料交換格式 import time de

python 爬蟲2-正則表達式抓職位信息

headers mode data .cn 保存 time exc href ace import requestsimport re #正則表達式import time import pandas #保存成 CSV #header={‘User-Agent‘:‘M

ruby 爬蟲職位信息,產生詞雲報告

content 數據持久化 lag works wid spa 代碼 職位 要求 思路:1.獲取拉勾網搜索到職位的頁數    2.調用接口獲取職位id    3.根據職位id訪問頁面,匹配出關鍵字    url訪問采用unirest,由於拉鉤反爬蟲,短時間內頻繁訪問會被

selelinum+PhantomJS 職位

one while 對象 bili exe 5.0 設置 expect money 使用selenium+PhantomJS爬取拉鉤網職位信息,保存在csv文件至本地磁盤 拉鉤網的職位頁面,點擊下一頁,職位信息加載,但是瀏覽器的url的不變,說明數據不是發送get請求得到的