數據分析之路——(一)Python拉勾網爬蟲實戰

原文鏈接:https://zhuanlan.zhihu.com/p/98747651

想要進行數據分析,首先就是要有數據。那么數據如何獲取呢?

當然網上有各種公開的數據或者數據接口,例如政府公開的數據,企業、公益組織公開的數據等等。

但是并不是所有的數據都能從網上找到,這時候就需要我們寫爬蟲來爬取數據(自己動手,豐衣足食嘛)。

學習了數據分析,我們最關心的當然是找工作啦。那么這里就以爬取拉勾網的數據分析職位數據作為實戰,寫一個我們自己的爬蟲。

1 準備工作

我們用到的python庫有:requests和pandas。requests是最常用的構造和解析http請求的庫,pandas是進行數據分析一定會使用的庫,提供了數據分析需要使用的各種工具,這里我們使用的是to_csv來存儲數據。

抓包工具:為了更好地分析請求,建議下載一個抓包工具(也可以直接通過瀏覽器的Network進行分析,但是不如使用抓包工具方便),可以把流量進行重放,便于分析。這里使用的是Burp Suite Free Edition,這也是網絡安全人員常用的工具。

2 分析請求

打開chrome瀏覽器,在網頁中輸入“數據分析“,打開F12。

點擊第一條請求,切換到Preview查看json格式化后到響應,發現這就是我們想要找的請求。

3 Python構造請求

切到Headers,提取出我們需要的信息:請求地址Request URL,請求方式POST,請求body中的數據Form Data。這里還需要把Response Headers中的信息一起帶到請求的Header中,包括瀏覽器信息User-agent、跨域相關的Origin、以及Cookie等信息,總之全部帶過來。

好了,現在我們構造第一條請求



于是我們獲取了第一頁的數據。從請求中可以看到,pn是頁數,那么把pn從1到最后一頁,遍歷一遍,是不是就能爬取所有數據呢?結果是不行。當爬取到第6頁時,返回結果出錯了

原因是沒有content這個鍵值。我們修改下請求,直接打印response

r = requests.post('https://www.lagou.com/jobs/positionAjax.json', headers=headers, params=params, cookies=cookies, data=data)

response = r.json()

print(response)


好吧,說我們操作太頻繁。當然不能這么輕易就讓我們爬取所有數據啦,因為拉勾網使用了反爬策略。

4 分析反爬策略

如何分析反爬策略呢?

這時候我們的抓包工具就出場了。這里就不介紹具體用法了,網上一堆教程(注意這里是https請求,burp需要導入證書)。

我們用抓包工具抓取第一頁和第六頁的請求,發送到comparer中進行比較

標紅的表示cookie中字段發生了變化,同時body中多了一個sid字段。我們知道,cookie中的字段發生變化,通常需要在response頭中使用Set-Cookie來設置。仔細查看歷史請求,下面這條請求引起了我們的注意,把它放到repeater中進一步分析

嘗試把Cookie置空,在響應中會重新Set-Cookie

由此,我們聯想到,是不是當Cookie中某些字段失效的時候,我們只要重新發送這條請求,獲取新的Cookie,就可以繞過反爬策略了?我們修改一下代碼,并引入pandas來存儲結果到csv中

import requests

import time

import pandas as pd

import math

# 獲取新的Cookie

def get_cookie():

? ? headers = {

? ? ? ? 'Accept': 'application/json, text/javascript, */*; q=0.01',

? ? ? ? 'Accept-Encoding': 'gzip, deflate, br',

? ? ? ? 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',

? ? ? ? 'Connection': 'keep-alive',

? ? ? ? 'Upgrade-Insecure-Requests': '1',

? ? ? ? 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36',

? ? ? ? 'Sec-Fetch-User': '?1'

? ? }

? ? pre_response = requests.get(

? ? ? ? 'https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/p-city_3?&cl=false&fromSearch=true&labelWords=&suginput=',

? ? ? ? headers=headers)

? ? cookies = {

? ? ? ? 'user_trace_token': '20191221100243-986eaba8-84ce-47bd-804f-6015e977b6e6',

? ? ? ? 'LGUID': '20190824091904-293ded79-c60d-11e9-a504-5254005c3644',

? ? ? ? 'JSESSIONID': 'ABAAABAABEEAAJA24A5C810F59E6988A2A3495180E65450',

? ? ? ? 'index_location_city': '%E4%B8%8A%E6%B5%B7',

? ? ? ? 'X_HTTP_TOKEN': '42daf4b72327b2813673986751bf5e71415983ed09',

? ? ? ? 'SEARCH_ID': '74d7631fe0ec4f3fa7badce24c42e3be'

? ? }

? ? # 轉成dict

? ? cookie = requests.utils.dict_from_cookiejar(pre_response.cookies)

? ? cookies.update(cookie)

? ? return cookies

# 爬取數據

def get_data(cookies, page):

? ? headers = {

? ? ? ? 'Origin': 'https://www.lagou.com',

? ? ? ? 'X-Anit-Forge-Code': '0',

? ? ? ? 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',

? ? ? ? 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36',

? ? ? ? 'X-Requested-With': 'XMLHttpRequest',

? ? ? ? 'X-Anit-Forge-Token': 'None',

? ? ? ? 'Sec-Fetch-Site': 'same-origin',

? ? ? ? 'Sec-Fetch-Mode': 'cors',

? ? ? ? 'Referer': 'https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90?labelWords=&fromSearch=true&suginput='

? ? }

? ? # url中的參數

? ? params = {

? ? ? ? 'city': '上海',

? ? ? ? 'needAddtionalResult': 'false'

? ? }

? ? # body中的參數,第一頁和后面頁數參數不同

? ? if page == 1:

? ? ? ? data = {

? ? ? ? ? ? 'first': 'true',

? ? ? ? ? ? 'pn': '1',

? ? ? ? ? ? 'kd': '數據分析'

? ? ? ? }

? ? else:

? ? ? ? data = {

? ? ? ? ? ? 'first': 'false',

? ? ? ? ? ? 'pn': page,

? ? ? ? ? ? 'kd': '數據分析',

? ? ? ? ? ? 'sid': '0144b1f08bdc48c8ba656dc8a18b746c'

? ? ? ? }

? ? r = requests.post('https://www.lagou.com/jobs/positionAjax.json', headers=headers, params=params, cookies=cookies,

? ? ? ? ? ? ? ? ? ? ? data=data)

? ? response = r.json()['content']['positionResult']

? ? result = response['result']

? ? # dict轉成dataFrame

? ? response_to_df = pd.DataFrame.from_dict(result)

? ? global df

? ? # 添加到全局df中

? ? df = df.append(response_to_df, ignore_index=True)

? ? # 獲取總頁數

? ? total_page = math.ceil(response['totalCount'] // response['resultSize'])

? ? # 返回是否已經最后一頁,用來跳出循環

? ? return page >= total_page

# 初始獲取Cookie

cookies = get_cookie()

# 初始化頁數

page = 1

# 創建DataFrame,用于存儲數據

df = pd.DataFrame()

# 循環,直到最后一頁

while (1):

? ? if page % 4 == 0:

? ? ? ? cookies = get_cookie()

? ? end = get_data(cookies=cookies, page=page)

? ? if end:

? ? ? ? break

? ? else:

? ? ? ? page += 1

? ? time.sleep(5)

# 默認encoding=utf-8會導致excel打開亂碼

df.to_csv('lagou.csv', sep=',', header=True, encoding='GBK')

與數據分析相關的還有數據挖掘,我們也來爬一下,一共389條數據

至此,我們完成了第一個爬蟲,獲取了拉勾網上數據分析相關職位的數據。

數據得到了,下一節將會對爬取到的數據進行分析。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容