摘要:因為本人在成都從事前端,所以這次爬取的關鍵詞既是成都,前端。僅僅有這個是不夠的,因為貌似拉勾網有反爬蟲,沒有好像得不到數據這個還待論證,至少我這邊是。
前言
今天是2018的第一天,首先祝各位小伙伴元旦快樂!
又到了新的一年,雖然離春節還有一段時間,但是程序狗打工不易啊,不關注薪資怎么行。今天要做的就是用圖表統計一下現在各公司的薪資狀況(雖然很多公司不能按照招聘上他們給的薪資來給)。
本次使用scrapy來做數據爬取,這是一個python的框架。因為本人在成都從事web前端,所以這次爬取的關鍵詞既是:成都,web前端。
scrapy startproject lagou
首先通過運行命令,得到一個爬蟲項目的基礎結構。
接著按照scrapy的中文教程,通過在
start_urls = [ "https://www.lagou.com/jobs/list_web%E5%89%8D%E7%AB%AF?labelWords=sug&fromSearch=true&suginput=web" ]
spider中的start_urls配置好,應該就能把拉勾網頁面拉取下來,然后再分析dom,提取字符串就可以了,無奈這種方法并不行。
起初也不知道,就用xpath一直找,后來發現找不到會報錯,這些各種錯誤對于我這個爬蟲萌新還是懵逼的。仔細查看他的network發現,他的招聘信息都是在另外的ajax請求當中,并且還是整理好的。
因為本人工作1年多,所以主要關注點是3年以下及3-5年,就提前選好了,城市和工作年限。該請求的傳參是formdata,其中first是首頁(其實寫代碼的時候并沒有注意這個參數,所以一直傳的是true,貌似也沒什么影響),pn是當前頁數,kd是關鍵詞。
于是乎就去文檔查閱了一下,如何在scrapy中循環發送formdata請求。最終得到這樣一段可以執行的代碼。
def start_requests(self): url = "https://www.lagou.com/jobs/positionAjax.json?gj=3%E5%B9%B4%E5%8F%8A%E4%BB%A5%E4%B8%8B%2C3-5%E5%B9%B4&xl=%E6%9C%AC%E7%A7%91&px=default&city=%E6%88%90%E9%83%BD&needAddtionalResult=false&isSchoolJob=0" for i in range(1, 14): formdata = {"first": "true", "pn": str(i), "kd": "web前端"} yield scrapy.FormRequest(str(url), callback=self.parseJson, formdata=formdata)
start_requests是發送post請求的方法,FormRequest這個方法接收請求url,傳遞數據formdata,以及回調函數parseJson。parseJson在這里主要是接收獲取的數據。
僅僅有這個是不夠的,因為貌似拉勾網有反爬蟲,沒有header好像得不到數據(這個還待論證,至少我這邊是)。然后再settings.py文件中做了一些配置,配置主要有:
請求的header(主要是這幾項)
DEFAULT_REQUEST_HEADERS={ Accept:application/json, text/javascript, */*; q=0.01 Host:www.lagou.com Origin:https://www.lagou.com Referer:https://www.lagou.com/jobs/list_web%E5%89%8D%E7%AB%AF?px=default&gj=3%E5%B9%B4%E5%8F%8A%E4%BB%A5%E4%B8%8B,3-5%E5%B9%B4&city=%E6%88%90%E9%83%BD User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36 }
FEED_EXPORT_ENCODING(因為爬取到的中文是unicode字符)
FEED_EXPORT_ENCODING = "utf-8"
ROBOTSTXT_OBEY(這是一個爬蟲機器的協議,如果是true,表示遵守,有些網站禁止爬取的話,這個如果是true就爬不到了)
ROBOTSTXT_OBEY = False
DOWNLOAD_DELAY(延時,這個也是去避免被反爬蟲,我這邊直接設置了比較長的時間,也沒有去測試多少合適,因為不設置也是會報錯的)
DOWNLOAD_DELAY = 10
基礎的配置項配置完畢之后,就是寫數據存儲的模型了,因為我只想去簡單統計一下,所以只存了薪資和工資這兩個字段,想要統計更多的信息,就直接繼續加就好了,這個比較簡單,在items.py中編寫
class LaGou(scrapy.Item): salary = scrapy.Field() company = scrapy.Field()
經過這幾項配置,運行命令
scrapy crawl lagou -o a.json
就可以得到一份a.json,里面就是成都web前端相關,工作年限為0-5年的數據信息了。有了這份數據,接下來要做的就是數據處理了。
數據處理在之前的a.json當中,大致可以得到一份之下的數據,總計195條
[ {"salary": "8k-16k", "company": "xx有限公司"}, ...... ]
為了前端處理方便,直接改為js文件加一個變量引入html,即
var a = [ {"salary": "8k-16k", "company": "xx有限公司"}, ...... ]
這組數據的薪資是一個范圍,不方便我統計,于是為了便于操作數據把薪資取平均值,并統計提供相同的薪資的公司數目。
js代碼如下:
var arr = data.map(function (value) { return value.salary && value.salary.replace(/k|K/g, "").split("-").reduce(function (pV, nV) { return pV + nV / 2 }, 0) }).reduce(function (pV, nV) { nV in pV ? pV[nV]++ : (pV[nV] = 1); return pV; }, {}) //這里的data既是上邊的a變量
這段代碼主要作用是把薪資范圍計算成平均數,然后再統計數組中相同的平均數的個數。代碼寫的隨意,可讀性較差,見諒。這段代碼處理過后,可得到類似如下數據:
{"8":1,"8.5":3}
key是薪資均值,value是個數。
于是將key,value分別存入數組。這里遇到一個問題,就是開始我是這樣操作的
var xData=[...Object.keys(arr)] var yData=[...Object.values(arr)]
這么做有一個問題就是瀏覽器對于對象的遍歷規則,導致輸出的數組,小數都到了最外邊(比如這樣[1,2,1.5]),這樣在echarts下的圖表是亂序的。也沒有想到好的辦法去解決,就是對數組進行一次排序,然后再根據排好的key生成相對應的value數組,最終代碼:
var xData = [...Object.keys(arr).sort(function (a, b) { return a - b })] var yData = xData.map(function (v) { return arr[v] })
echarts比較簡單不贅述。將這兩組橫縱坐標輸入echarts,得到最終效果:
本次做這個統計很多地方沒想清楚怎么更好的去表現,所以做的很簡單,其實細致一點還可以去分類統計,按照公司融資情況,領域等等內容,只要數據拿到都好說。另外很多地方可能寫的不夠好,主要我目前也不太會寫,比如之前反爬蟲那塊,貌似去做動態的用戶代理也能行,但我還是增加了延時,選擇了比較笨的方法。另外也不會python,但還好python比較好讀。因為這一塊才開始學習,相信以后會越寫越好的,新的一年,加油!
update 2018/01/03昨天又把爬蟲優化了一下,去掉了之前的延時,增加了動態用戶代理和動態IP代理,解決了之前爬蟲的效率問題,也擴大了數據量。
動態IP代理通過網上搜索免費的ip代理,獲取了如下一組ip:
PROXIES = [ {"ip_port": "106.39.179.244:80"}, {"ip_port": "65.52.223.99:80"}, {"ip_port": "1.52.248.207:3128"}, {"ip_port": "45.77.198.207:3128"}, {"ip_port": "177.125.119.16:8080"}, {"ip_port": "174.138.65.233:3128"}, ]
該IP過一段時間可能會失效,請自行搜索,如http://www.xicidaili.com/。
在middlewares.py中聲明該IP,之后聲明動態IP代理類
import random class ProxyMiddleware(object): def process_request(self, request, spider): proxy = random.choice(PROXIES) request.meta["proxy"] = "http://%s" % proxy["ip_port"] print("**************ProxyMiddleware no pass************" + proxy["ip_port"])
在settings.py文件中聲明該中間件
DOWNLOADER_MIDDLEWARES = { "scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware": 110, "tutorial.middlewares.ProxyMiddleware": 100, }動態用戶代理
在middlewares.py中聲明動態用戶代理類
class RandomUserAgent(object): """Randomly rotate user agents based on a list of predefined ones""" def __init__(self, agents): self.agents = agents @classmethod def from_crawler(cls, crawler): return cls(crawler.settings.getlist("USER_AGENTS")) def process_request(self, request, spider): # print "**************************" + random.choice(self.agents) request.headers.setdefault("User-Agent", random.choice(self.agents))
同樣在settings.py的中間件里聲明
DOWNLOADER_MIDDLEWARES = {
"tutorial.middlewares.RandomUserAgent": 1, "scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware": 110, "tutorial.middlewares.ProxyMiddleware": 100,
}
再次運行scrapy crawl lagou,即可得到新的數據。
在原有基礎上增加了對于工作年限和公司規模的篩選,并計算了平均值。
更新代碼如下:
// 指定圖表的配置項和數據 initData(); function initData() { average = 0; arr = temData.map(function (value) { //之前正則篩選字符串有點問題,沒有考慮到有些公司格式為10k以上這種。 return value.salary && value.salary.replace(/[k|Ku4e00-u9fa5]/g, "").split("-").reduce(function (pV, nV, i, array) { if (array.length > 1) { average = Number(average) + pV + nV / 2 return pV + nV / 2 } else { average = +average + Number(nV) return nV } // return array.length > 1 ? pV + nV / 2 : nV }, 0) }).reduce(function (pV, nV) { nV in pV ? pV[nV]++ : (pV[nV] = 1); return pV; }, {}) average = (average / temData.length).toFixed(2) }
暫時這樣,通過之后的學習,還會不斷的優化。
展示效果:
源碼地址:https://github.com/jiwenjiang...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/41165.html
摘要:因為本人在成都從事前端,所以這次爬取的關鍵詞既是成都,前端。僅僅有這個是不夠的,因為貌似拉勾網有反爬蟲,沒有好像得不到數據這個還待論證,至少我這邊是。 前言 showImg(https://segmentfault.com/img/bV1g4S?w=700&h=490); 今天是2018的第一天,首先祝各位小伙伴元旦快樂!又到了新的一年,雖然離春節還有一段時間,但是程序狗打工不易啊,不...
摘要:然后準備再去抓下拉勾網的招聘數據,這也是個相對優秀的專業招聘網站了,數據也相當多,想當初找實習找正式工作,都是在這兩個上找的,其他的網站幾乎都沒看。 原文地址:http://www.jtahstu.com/blog/s... Pyhton爬蟲實戰 - 抓取BOSS直聘職位描述 和 數據清洗 零、致謝 感謝BOSS直聘相對權威的招聘信息,使本人有了這次比較有意思的研究之旅。 由于爬蟲持續...
摘要:然后準備再去抓下拉勾網的招聘數據,這也是個相對優秀的專業招聘網站了,數據也相當多,想當初找實習找正式工作,都是在這兩個上找的,其他的網站幾乎都沒看。 原文地址:http://www.jtahstu.com/blog/s... Pyhton爬蟲實戰 - 抓取BOSS直聘職位描述 和 數據清洗 零、致謝 感謝BOSS直聘相對權威的招聘信息,使本人有了這次比較有意思的研究之旅。 由于爬蟲持續...
摘要:愛寫作者愛寫前言看了很多網站,只發現獲取拉勾網招聘信息是只用方式就可以得到,應當是非常簡單了。在環境下運行通過數據爬取篇偽造瀏覽器訪問拉勾網打開瀏覽器,進入拉勾網官網,右鍵檢查,調出開發者模式。 [TOC] 愛寫bug(ID:icodebugs)作者:愛寫bug 前言: ? 看了很多網站,只發現獲取拉勾網招聘信息是只用post方式就可以得到,應當是非常簡單了。推薦剛接觸數據分析...
摘要:拉勾網的爬蟲還是有一定的難度的所以我們今天就爬取試一下其實并沒有太大的難度只要我們用好分析一下請求就會其實沒有什么難度上代碼親測可用拉鉤代碼 拉勾網的爬蟲還是有一定的難度的 所以我們今天就爬取試一下 其實并沒有太大的難度 只要我們用好network 分析一下請求 就會其實沒有什么難度 上代碼 2019-05-22 親測可用 拉鉤代碼
閱讀 2951·2021-11-25 09:43
閱讀 3327·2021-11-24 09:39
閱讀 2828·2021-09-22 15:59
閱讀 2174·2021-09-13 10:24
閱讀 509·2019-08-29 17:02
閱讀 2098·2019-08-29 13:23
閱讀 3058·2019-08-29 13:06
閱讀 3539·2019-08-29 13:04