99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀R語言爬蟲初嘗試-基于RVEST包學(xué)習(xí)
R語言爬蟲初嘗試-基于RVEST包學(xué)習(xí)
2017-01-11
收藏

R語言爬蟲初嘗試-基于RVEST包學(xué)習(xí)

在學(xué)完coursera的getting and Cleaning data后,繼續(xù)學(xué)習(xí)用R弄爬蟲網(wǎng)絡(luò)爬蟲。主要用的還是Hadley Wickham開發(fā)的rvest包。再次給這位矜矜業(yè)業(yè)開發(fā)各種好用的R包的大神奉上膝蓋

查閱資料如下:

rvest的github

rvest自身的幫助文檔

rvest + CSS Selector 網(wǎng)頁數(shù)據(jù)抓取的最佳選擇-戴申: 里面有提及如何快速獲得html的位置??赐赀@篇,想想我之前看代碼看半天分段真是逗比。。經(jīng)測試,遨游瀏覽器,右鍵,審查元素可以得到類似結(jié)果。戴申的blog里面還有若干相關(guān)文章,國內(nèi)RVEST資料基本就靠他的BLOG了,感激!

言歸正傳,拿了幾個(gè)網(wǎng)頁練手。包括對拉勾網(wǎng)爬了一下蟲,還嘗試了對國外某黃頁爬蟲,對ebay用戶評價(jià)爬蟲分析其賣家賣的東西主要在哪個(gè)價(jià)格段(我查的那個(gè)賣家,賣8.99和39.99最多,鞋子類),做了一下文本挖掘,還有爬了一下股票數(shù)據(jù),基金買入情況等等。

之所以放拉勾網(wǎng)為例子,因?yàn)檫@個(gè)大家都比較熟一點(diǎn)?其他的都有點(diǎn)小眾=_=而且雖然我沒有跳槽的心,但年初卻是很多人跳槽的熱點(diǎn)。另外,因?yàn)橹奥犎苏f過,要了解一個(gè)公司的動(dòng)態(tài),有一個(gè)辦法是去看這個(gè)公司放出來的招聘崗位,可以知道他們最近哪個(gè)業(yè)務(wù)線要擴(kuò)張了,哪個(gè)業(yè)務(wù)線要跑人了,以及了解技術(shù)需求。

rvest基礎(chǔ)語法:

library(rvest)
lagou<-"http://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90?kd=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90&spc=2&pl=&gj=&xl=&yx=&gx=&st=&labelWords=&lc=&workAddress=&city=%E6%B7%B1%E5%9C%B3&requestId=&pn=3"
web<-html(lagou,encoding="UTF-8") #讀取數(shù)據(jù),規(guī)定編碼
#之前我是用關(guān)鍵字搜索,閱讀html代碼,獲得html_nodes里需要什么屬性,不過許多瀏覽器有開發(fā)者工具,可以直接獲得層級信息。如遨游
position<-web %>% html_nodes("li div.hot_pos_l a") %>% html_text()
#上面就是直接讀取數(shù)據(jù),獲得位置信息
#不過在后面做其他網(wǎng)站時(shí)發(fā)現(xiàn),有時(shí)候信息儲(chǔ)存在同類數(shù)據(jù)里(如div沒有class等等),建議是找一個(gè)大的分類,先獲得表格信息,再做數(shù)據(jù)
list_lagou<-web %>% html_nodes("li.clearfix")
#這里正確找準(zhǔn)正確的劃分點(diǎn)很重要。有<li class="odd clearfix">,其實(shí)用li.clearfix一樣可以取(對于空格二選一,如"li.odd"或者"li.clearfix")
#接下來的company/position照選即可,因?yàn)槭孪纫呀?jīng)分好了list,所以每一個(gè)出多少心里有數(shù)。。

在講完原理之后,現(xiàn)在開始嘗試寫代碼

因?yàn)槔锩嫔婕疤嗟倪x取數(shù)據(jù)工作。為了避免出現(xiàn)太多變量,我最后是編了一個(gè)函數(shù),輸出數(shù)據(jù)庫

函數(shù)部分

#下面開始寫代碼,首先寫一個(gè)函數(shù)getdata,會(huì)輸出一個(gè)數(shù)據(jù)框
getdata<-function(page,urlwithoutpage){
        url=paste0(urlwithoutpage,page) #這里輸入拉勾網(wǎng)沒有頁碼的url
        web<-html(url,encoding="UTF-8") #讀取數(shù)據(jù),規(guī)定編碼,access用
        list_lagou<-web %>% html_nodes("li.clearfix") #獲得一個(gè)清單,15個(gè)職位
        title<-list_lagou %>% html_nodes("div.hot_pos_l div.mb10 a")%>%html_text()
        company<-list_lagou %>% html_nodes("div.hot_pos_r div.mb10 a")%>%html_text()
        link<-gsub("\\?source\\=search","",list_lagou %>% html_nodes("div.hot_pos_l div.mb10 a")%>%html_attr("href"))
#接下來的由于數(shù)據(jù)都存在span里,沒有很好的劃分。這個(gè)取數(shù)要復(fù)雜一些。我在這里,研究他們的表,先取15個(gè)完整list,然后用seq等序列取數(shù)
#之后要研究是否有更好的方法
#如果有table,可以直接用data.table取數(shù)更快。。。
        temp<-list_lagou %>% html_nodes("div.hot_pos_l span")
        city<-temp[seq(1,90,by=6)] %>% html_text()
        salary<-gsub("月薪:","",temp[seq(2,90,by=6)]%>% html_text())
        year<-gsub("經(jīng)驗(yàn):","",temp[seq(3,90,by=6)]%>% html_text())
        degree<-gsub("最低學(xué)歷:","",temp[seq(4,90,by=6)]%>%html_text())
        benefit<-gsub("職位誘惑:","",temp[seq(5,90,by=6)]%>% html_text())
        time<-temp[seq(6,90,by=6)]%>%html_text()
        data.frame(title,company,city,salary,year,degree,benefit,time,link)
}

然后是使用該函數(shù),我這里就爬兩頁

#使用該函數(shù),
library(rvest)
url<-"http://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90?kd=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90&spc=2&pl=&gj=&xl=&yx=&gx=&st=&labelWords=&lc=&workAddress=&city=%E6%B7%B1%E5%9C%B3&requestId=&pn="
final<-data.frame()
for (i in 3:5){
        final<-rbind(final,getdata(i,url))        
} #定義個(gè)數(shù),把上面的getdata得到的Data.frame合并
head(final)

上面完成了第一個(gè)列表。爬出效果如圖

關(guān)于這個(gè)數(shù)據(jù)有什么用呢…… 簡單來說,我們可以用它來看這個(gè)網(wǎng)上有多少在招的,各公司招人的比例,以及薪資水平,做一點(diǎn)基礎(chǔ)的數(shù)據(jù)分析。

雖然我現(xiàn)在不跳槽,不過了解一下市場狀況也是不錯(cuò)的~譬如見下圖,從目前這網(wǎng)上的平均薪資與工作年限的關(guān)系來看,數(shù)據(jù)分析崗至少在職位前五年屬于薪資增長期,初始漲得快,后面漲得慢,但平均應(yīng)有13%左右的增長?然后這網(wǎng)上目前沒有什么高級崗位開出來(工作5-10年的崗位很少),反而是有些公司搞錯(cuò)分類,放了一堆數(shù)據(jù)錄入的到數(shù)據(jù)分析欄目。。。

值得一提的是,因?yàn)閿?shù)據(jù)分析這個(gè)類目里包含了不同的類別,如數(shù)據(jù)錄入的也被歸到數(shù)據(jù)分析,還有高薪也被歸到這里,所以不能完全按這個(gè)做參考。不過這個(gè)研究讓我深刻體會(huì)到了爬蟲的有效性!好玩!實(shí)用!可以用到工作中去:) 還可以像個(gè)獵頭一樣了解人才市場~~做個(gè)有情調(diào)的數(shù)據(jù)分析師~~

另外,其實(shí)我們還可以遍歷JD,看近期是什么技術(shù)最吃香,是R還是Python還是SQL還是SAS還是別的啥啥啥。下面是我隨機(jī)抽了個(gè)JD做的爬蟲。可以直接拿到相關(guān)數(shù)據(jù)。

final[1,9]
## [1] http://www.lagou.com/jobs/378361.html
## 45 Levels: http://www.lagou.com/jobs/113293.html ...
url<-as.character(final[1,9])
w<-html(url,encoding = "UTF-8")
d<-w %>% html_nodes("dd.job_bt p") %>% html_text()
d
## [1] "1.金融、計(jì)算機(jī)、財(cái)務(wù)、經(jīng)濟(jì)相關(guān)專業(yè);"
## [2] "2.有證券從業(yè)資格證者優(yōu)先;"          
## [3] "3.想從事文職類工作,對辦公軟件熟悉;"
## [4] "4.可接收已拿到學(xué)歷證的應(yīng)屆畢業(yè)生。"  
## [5] "<U+00A0>"

注意事項(xiàng):

對于被編碼保護(hù)的數(shù)據(jù)(如國外yellow.local.ch,email被編碼保護(hù)了。需要用 decodeURIComponent函數(shù)反編譯。)

xpath語句對html_nodes適用。但是它好像是全局語句。。就是如果用div[1]//span[4]取數(shù)的話,它直接就只出全局的那個(gè)結(jié)果。。。

取數(shù),可以用li.da或者li.daew取數(shù),兩者等價(jià)

正則表達(dá)式很有用??!尤其是對網(wǎng)頁數(shù)據(jù),某些不會(huì)寫,或者技術(shù)高超不愿意被我們爬蟲的工程師,用rvest去抓數(shù)據(jù),會(huì)抓到一堆堆亂碼= =這幾天練習(xí)下來感受到了無盡惡意

中文,html(data,encoding='UTF-8')還有iconv(data,'utf-8','gbk')可以有效避免大部分亂碼。但是R對中文支持真的很渣。

rvest對于靜態(tài)抓取很方便!但是對于腳本訪問的網(wǎng)頁,還需要繼續(xù)學(xué)習(xí)RCurl包。備查資料如下:

javascript數(shù)據(jù)提取-RCurl包-戴申: 介紹對腳本解析后抓取數(shù)據(jù)經(jīng)驗(yàn)

RCurl提取統(tǒng)計(jì)之都論壇數(shù)據(jù)演示-medo

 等學(xué)會(huì)了再寫總結(jié)。


數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺(tái)檢測極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }