源代碼: "https://github.com/nnngu/LagouSpider" 效果預覽 ![][7] 思路 1、首先我們打開拉勾網,並搜索“java”,顯示出來的職位信息就是我們的目標。 2、接下來我們需要確定,怎樣將信息提取出來。 查看網頁源代碼,這時候發現,網頁源代碼裡面找不到職位相關 ...
源代碼:https://github.com/nnngu/LagouSpider
效果預覽
思路
1、首先我們打開拉勾網,並搜索“java”,顯示出來的職位信息就是我們的目標。
2、接下來我們需要確定,怎樣將信息提取出來。
查看網頁源代碼,這時候發現,網頁源代碼裡面找不到職位相關信息,這證明拉勾網關於職位的信息是非同步載入的,這也是一種很常用的技術。
非同步載入的信息,我們需要藉助 chrome 瀏覽器的開發者工具進行分析,打開開發者工具的方法如下:
- 點擊Nerwork進入網路分析界面,這時候是一片空白,刷新一下界面就可以看到一系列的網路請求了。
前面我們說到,拉勾網關於職位的信息是非同步載入的,那麼在這一系列的網路請求中,必定有某個請求發送給伺服器,響應回來的是職位信息。
正常情況下,我們可以忽略css,圖片等類型的請求,關註點放在XHR這種類型請求上,如圖:
一共4個XHR類型的請求,我們逐個打開對比,分別點擊Preview就能看到它們響應的內容。
發現第一個請求就是我們要找的。如圖:
點擊Headers,查看一下請求參數。如下圖:
到此,我們可以確定city參數就是城市,pn參數就是頁數,kd參數就是搜索關鍵字。
接下來開始寫代碼了。
代碼
代碼分成四個部分,便於後期維護。
1、基本 https 請求https.py
這部分對 requests 包進行了一些封裝,部分代碼如下:
# -*- coding: utf-8 -*-
from src.setting import IP, UA
import requests, random
import logging
class Http:
'''
http請求相關的操作
'''
def __init__(self):
pass
def get(self, url, headers=None, cookies=None, proxy=None, timeOut=5, timeOutRetry=5):
'''
獲取網頁源碼
url: 網頁鏈接
headers: headers
cookies: cookies
proxy: 代理
timeOut: 請求超時時間
timeOutRetry: 超時重試次數
return: 源碼
'''
if not url:
logging.error('GetError url not exit')
return 'None'
# 這裡只展示了一部分代碼
# 完整代碼已上傳到Github
這裡只展示了一部分代碼,完整代碼已上傳到Github
2、代碼主邏輯部分main.py
這部分的程式邏輯,如下:
- 獲取職位信息
def getInfo(url, para):
"""
獲取信息
"""
generalHttp = Http()
htmlCode = generalHttp.post(url, para=para, headers=headers, cookies=cookies)
generalParse = Parse(htmlCode)
pageCount = generalParse.parsePage()
info = []
for i in range(1, 3):
print('第%s頁' % i)
para['pn'] = str(i)
htmlCode = generalHttp.post(url, para=para, headers=headers, cookies=cookies)
generalParse = Parse(htmlCode)
info = info + getInfoDetail(generalParse)
time.sleep(2)
return info
- 對信息進行儲存
def processInfo(info, para):
"""
信息存儲
"""
logging.error('Process start')
try:
title = '公司名稱\t公司類型\t融資階段\t標簽\t公司規模\t公司所在地\t職位類型\t學歷要求\t福利\t薪資\t工作經驗\n'
file = codecs.open('%s職位.xls' % para['city'], 'w', 'utf-8')
file.write(title)
for p in info:
line = str(p['companyName']) + '\t' + str(p['companyType']) + '\t' + str(p['companyStage']) + '\t' + \
str(p['companyLabel']) + '\t' + str(p['companySize']) + '\t' + str(p['companyDistrict']) + '\t' + \
str(p['positionType']) + '\t' + str(p['positionEducation']) + '\t' + str(
p['positionAdvantage']) + '\t' + \
str(p['positionSalary']) + '\t' + str(p['positionWorkYear']) + '\n'
file.write(line)
file.close()
return True
except Exception as e:
print(e)
return None
3、信息解析部分parse.py
這部分針對伺服器返回的職位信息的特點,進行解析,如下:
class Parse:
'''
解析網頁信息
'''
def __init__(self, htmlCode):
self.htmlCode = htmlCode
self.json = demjson.decode(htmlCode)
pass
def parseTool(self, content):
'''
清除html標簽
'''
if type(content) != str: return content
sublist = ['<p.*?>', '</p.*?>', '<b.*?>', '</b.*?>', '<div.*?>', '</div.*?>',
'</br>', '<br />', '<ul>', '</ul>', '<li>', '</li>', '<strong>',
'</strong>', '<table.*?>', '<tr.*?>', '</tr>', '<td.*?>', '</td>',
'\r', '\n', '&.*?;', '&', '#.*?;', '<em>', '</em>']
try:
for substring in [re.compile(string, re.S) for string in sublist]:
content = re.sub(substring, "", content).strip()
except:
raise Exception('Error ' + str(substring.pattern))
return content
# 這裡只展示了一部分代碼
# 完整代碼已上傳到Github
這裡只展示了一部分代碼,完整代碼已上傳到Github
4、配置部分setting.py
這部分加入 cookies 的原因是為了應對拉勾網的反爬,長期使用需要進行改進,進行動態 cookies 獲取
# -*- coding: utf-8 -*-
# headers
headers = {
'Host': 'www.lagou.com',
'Connection': 'keep-alive',
'Content-Length': '23',
'Origin': 'https://www.lagou.com',
'X-Anit-Forge-Code': '0',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'X-Requested-With': 'XMLHttpRequest',
'X-Anit-Forge-Token': 'None',
'Referer': 'https://www.lagou.com/jobs/list_java?city=%E5%B9%BF%E5%B7%9E&cl=false&fromSearch=true&labelWords=&suginput=',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7'
}
測試
運行結果:
爬取結束後,在src目錄下就可以看到爬蟲爬取到的數據。
到此,拉勾網的職位信息抓取就完成了。完整代碼已經上傳到我的Github