前程無憂爬蟲源碼及分析(一)


一、網頁分析

    1.1 關鍵字頁面(url入口)

        首先在前程無憂網站上檢索關鍵詞"大數據":

        跳轉到如下url: https://search.51job.com/list/000000,000000,0000,00,9,99,%25E5%25A4%25A7%25E6%2595%25B0%25E6%258D%25AE,2,1.html?lang=c&stype=&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&providesalary=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare=

        在這個url中,'%25E5%25A4%25A7%25E6%2595%25B0%25E6%258D%25AE'很明顯為某種編碼格式,我們知道'大數據'的UTF-8為'E5A4A7 E695B0 E68DAE',加上'%'變為16進制編碼,即'%E5%A4%A7%E6%95%B0%E6%8D%AE',這'25'又是什么鬼?百度得到到關鍵詞'二次編碼',%25的url編碼即為符號'%',所以'%25E5'即為'%E5'。不過我好奇的是,既然'%'已經是URI中的特殊轉義字符,為啥還要多此一舉地進行二次編碼呢。再查,發現'%'在URI中可能會引起程序解析的歧義,百分號本身就用作對不安全字符進行編碼時使用的特殊字符,因此本身需要編碼

        做一個實驗,我們將該url截取下來,用'銷售'中文的utf-8編碼代替其中的編碼,看看發生了什么。

        再回過頭去看在網站入口搜索框進去的'大數據'頁面:

        這是二次編碼過的,再在url里改成中文名:

        好吧,二次編碼與否並不影響效果。

        接下來來比較不同頁數URL之間的聯系。提取'大數據'關鍵詞前三頁url:

        將前兩頁進行對比:

        只有一個符號不同,再比較二、三頁:

        也是一個數字的差異,改數字即為頁碼。所以對於頁數url我們可以得出如下結論:

'https://search.51job.com/list/000000,000000,0000,00,9,99,關鍵詞 ,2,頁數.html?lang=c&stype=1&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare='

        因此入口url模塊代碼如下:

  1. if __name__ == '__main__':  
  2.     key = '銷售'  
  3.     urls = ['https://search.51job.com/list/000000,000000,0000,00,9,99,'+ key + ',2,{}.html?lang=c&stype=1&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare='.format(i) for i in range(1,50)]  
  4.     for url in urls:  
  5.         getUrl(url)  

 

    1.2 崗位詳情url

        由於我們需要的是崗位詳情頁面的信息,所以我們要找出頁面所有崗位的url。

        打開開發者工具,找到崗位名稱所在標簽,在屬性里發現了該頁面的url:

        又發現每一條招聘信息都在<div class="el">…</div>里:

所以通過如下xpath將url提取出來:

  1. //*[@id="resultList"]/div/p/span/a/@href  

 

    1.3 崗位信息提取

        進入某一崗位具體信息url,打開開發者選項,在信息所在標簽上右擊,提取所需信息的xpath。

  1. title = selector.xpath('/html/body/div[3]/div[2]/div[2]/div/div[1]/h1/text()')  
  2. salary = selector.xpath('/html/body/div[3]/div[2]/div[2]/div/div[1]/strong/text()')  
  3. company = selector.xpath('/html/body/div[3]/div[2]/div[2]/div/div[1]/p[1]/a[1]/text()')  
  4. place = selector.xpath('/html/body/div[3]/div[2]/div[2]/div/div[1]/p[2]/text()[1]')  
  5. exp = selector.xpath('/html/body/div[3]/div[2]/div[2]/div/div[1]/p[2]/text()[2]')  
  6. edu = selector.xpath('/html/body/div[3]/div[2]/div[2]/div/div[1]/p[2]/text()[3]')  
  7. num = selector.xpath('/html/body/div[3]/div[2]/div[2]/div/div[1]/p[2]/text()[4]')  
  8. time = selector.xpath('/html/body/div[3]/div[2]/div[2]/div/div[1]/p[2]/text()[5]')  
  9. comment = selector.xpath('/html/body/div[3]/div[2]/div[3]/div[1]/div/p/text()')  
  10. url = res.url  

    跑一遍看看,

        咦,怎么崗位要求這么多null?點一個進去看看

        嗯,<div>標簽下咋又出現了<div>,真是亂來(笑)。看來得換個法子了,把這個父<div>標簽下的中文全部帶走。這兒需要用到xpath的steing()函數。將上述方法改造,得到新的xpath:

  1. string(/html/body/div[3]/div[2]/div[3]/div[1]/div)  

    又能跑起來了,不過把該<div>里一些其他信息也帶進來了,比如崗位分類等。

 

 

二、一些細節

    2.1 編碼問題

        雖然沒有系統的學過編碼,但是在與不同網頁、不同的操作系統打交道的過程中也略知一二了。與前些天爬過的智聯招聘不同,前程無憂網頁用的是GBK編碼,所以需要注意編碼格式。而且還有一個小問題:

        對,報錯了,'\ufffd'無法被轉碼。從網上找來的解釋稱:

在通過GBK從字符串獲取字節數組時,由於一個Unicode轉換成兩個byte,如果此時用ISO-8859-1或用UTF-8構造字符串就會出現兩個問號。

若是通過ISO-8859-1構造可以再通過上面所說的錯上加錯恢復(即再通過從ISO-8859-1解析,用GBK構造);

若是通過UTF-8構造則會產生Unicode字符"\uFFFD",不能恢復,若再通過StringUTF-8ByteArrayGBKString,則會出現雜碼,如a錕斤拷錕斤拷

        而在Unicode中,\uFFFD為占位符,當從某語言向Unicode轉化時,如果在某語言中沒有該字符,得到的將是Unicode的代碼"\uffffd"。

        針對這種情況,在打開文件時可設置一個參數——errors:設置不同錯誤的處理方案,默認為 'strict',意為編碼錯誤引起一個UnicodeError。所以我們需要為該參數換一個值:ignore,當遇到編碼問題市直接無視。

  1. fp = open('51job.csv','wt',newline='',encoding='GBK',errors='ignore')  
  2. writer = csv.writer(fp)  
  3. '''''title,salary,company,place,exp,edu,num,time,comment,url'''  
  4. writer.writerow(('職位','薪水','公司','地區','經驗','學歷','數量','時間','要求','url'))  

 

    2.2 網頁結構問題

        電腦端的結構太多了…數據抓取率也低,代碼還得改改,還是移動適配又好看又好爬。

 

三、源代碼

    因為在寫這篇博客的時候,發現了一些之前沒發現的問題,並且有了優化的想法,所以就不把代碼貼過來了,就留github 吧,這些天再把這個項目改進一下。

    源代碼地址:51job源代碼地址

    相關:智聯招聘源代碼講解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM