爲了瞭解跟python數據分析有關行業的信息,大概地瞭解一下對這個行業的要求以及薪資情況,我決定從網上獲取信息並進行分析。既然想要分析就必需要有數據,因而我選擇了拉勾,冒着危險深刻內部,從他們那裏獲得了信息。不得不說,拉勾的反爬技術還挺厲害的,稍後再說明。話很少說,直接開始。html
每次爬蟲都要有明確的目的,剛接觸隨便找東西試水的除外。我想要知道的是python數據分析的要求以及薪資情況,所以,薪資、學歷、工做經驗以及一些任職要求就是個人目的。python
既然明確了目的,咱們就要看一下它們在什麼位置,因此咱們打開瀏覽器,尋找目標。像拉勾這種網站他們的信息通常都是經過ajax加載的,並且在輸入「python數據分析」敲擊回車以後跳轉的頁面,招聘信息不是一開始就顯示出來的,經過點擊頁碼也只是招聘信息在變化甚至連network都沒多大變化,能夠大膽猜想他是經過post請求的,因此咱們只關注post請求以及XHR文件,很快就發現了咱們要的東西。git
點擊preview可見詳細信息以json形式保存着,其中‘salary’、‘workYear’、‘education’、‘positionID’(招聘信息詳情頁有關的id)是咱們要的。再觀察一下它的form data,其中kd=關鍵字,pn=pageNum(頁碼)這是咱們請求的時候要帶上的參數。另外咱們要注意請求頭的referer參數,待會兒要用。知道了目標以後,爬起來!github
先設置請求頭headers,把平時用的user-agent帶上,再把formdata也帶上,用requests庫直接requests.post(url, headers=headers, data=formdata),而後就開始報錯了:{"status":false,"msg":"您操做太頻繁,請稍後再訪問","clientIp":"......","state":2402}。ajax
解決這個問題的關鍵在於,瞭解拉勾的反爬機制:在進入python數據分析招聘頁以前,咱們要在主頁,不妨叫它start_url輸入關鍵字跳轉。在這個過程當中,服務器會傳回來一個cookies,若是帶着這個cookies請求的話咱們就能夠獲得要的東西,因此要先請求start_url獲取cookies在請求目標url,並且在請求目標地址的話還要帶上referer這個請求頭參數,referer的含義大概是這樣:告訴服務器我是從哪一個頁面連接過來的,服務器基此能夠得到一些信息用於處理。另外,睡眠時間也要設置的長一點,否則很容易被封。知道了反爬機制以後,話很少說,直接上代碼。json
'''瀏覽器
@author: Max_Lyu服務器
Create time: 2019/4/1cookie
url: https://github.com/MaxLyu/Lagou_Analyzesession
'''
# 請求起始 url 返回 cookies
def get_start_url(self): session = requests.session() session.get(self.start_url, headers=self.headers, timeout=3) cookies = session.cookies return cookies # 將返回的 cookies 一塊兒 post 給 target_url 並獲取數據
def post_target_url(self): cookies = self.get_start_url() pn = 1
for pg in range(30): formdata = { 'first': 'false', 'pn': pn, 'kd': 'python數據分析' } pn += 1 response = requests.post(self.target_url, data=formdata, cookies=cookies, headers=self.headers, timeout=3) self.parse(response) time.sleep(60) # 拉勾的反扒技術比較強,短睡眠時間會被封
# 解析 response,獲取 items
def parse(self, response): print(response) items = [] print(response.text) data = json.loads(response.text)['content']['positionResult']['result'] if len(data): for i in range(len(data)): positionId = data[i]['positionId'] education = data[i]['education'] workYear = data[i]['workYear'] salary = data[i]['salary'] list = [positionId, education, workYear, salary] items.append(list) self.save_data(items) time.sleep(1.3)
其中save_data(items)是保存文件,我是保存在csv文件。篇幅有限,這裏就不展現了。
上面說了positionID 是爲了獲取詳情頁,詳情頁裏面有要的任職要求。這個要獲取就相對容易了,不過文本的處理並無很簡單,我只能經過「要求」這兩個字獲取任職要求(雖然有的爲任職技能啥的,就這樣進行取捨了)。
'''
@author: Max_Lyu
Create time: 2019/4/1
url: https://github.com/MaxLyu/Lagou_Analyze
'''
def get_url(): urls = [] with open("analyst.csv", 'r', newline='') as file: # 讀取文件
reader = csv.reader(file) for row in reader: # 根據 positionID 補全 url
if row[0] != "ID": url = "https://www.lagou.com/jobs/{}.html".format(row[0]) urls.append(url) file.close() return urls # 獲取詳細信息
def get_info(): urls = get_url() length = len(urls) for url in urls: print(url) description = ''
print(length) response = requests.get(url, headers=headers) response.encoding = 'utf-8' content = etree.HTML(response.text) detail = content.xpath('//*[@id="job_detail"]/dd[2]/div/p/text()') print(detail) for i in range(1, len(detail)): if '要求' in detail[i-1]: for j in range(i, len(detail)): detail[j] = detail[j].replace('\xa0', '') detail[j] = re.sub('[、;;.0-9。]', '', detail[j]) description = description + detail[j] + '/'
print(description) write_file(description) length -= 1 time.sleep(3)
到這裏,爬取的任務就結束了,源碼地址:https://github.com/MaxLyu/Lagou_Analyze 。得到數據以後就是小小地分析一下了,這個下次再總結。