关于
一直埋头学习,不知当前趋势,这是学习一门技术过程中最大的忌讳。刚好利用python爬虫,抓取一下拉勾网关于python职位的一些基本要求,不仅能知道岗位的基本技能要求,还能锻炼一下代码能力,学以致用,一举两得。
准备
工具 :python 2.7,PyCharm
类库:urllib2、BeautifulSoup、time、re、sys、json、collections、xlsxwriter
分析及代码实现
进入拉勾网进行分析,要想获取每个岗位的关键词,首先要知道每个岗位详情页面的url,通过对比我们发现,https://www.lagou.com/jobs/4289433.html中,只有4289433这一串数字是不同的,那么就可以知道我们只要获取到每个岗位的这一串数字,我们就可以爬取每个岗位详情页面。
通过F12查看,我们可以看到xhr请求中https://www.lagou.com/jobs/positionAjax.json?px=default&city=%E5%8C%97%E4%BA%AC&needAddtionalResult=false的响应消息里的参数positionId的值为详情页面url的那串数字,如下图
首先我们通过分析可以看到这是个post请求且form的参数为first、pn、kd,通过不同岗位列表页面的请求,我们可以看到first的取值逻辑是pn为1的时候,first为true,当pn不为1的时候,first的取值为false(其中pn为岗位列表的页数),还有kd为一个固定值(这里是python)
到这里,具体的逻辑已经很清楚了,具体的代码实现如下:
def get_positionId(pn):
positionId_list = []
url = 'https://www.lagou.com/jobs/positionAjax.json?px=default&city=%E5%8C%97%E4%BA%AC&needAddtionalResult=false'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
'Referer': 'https://www.lagou.com/jobs/list_Python?px=default&city=%E5%8C%97%E4%BA%AC'
}
if pn == 1:
first = 'true'
else:
first = 'false'
data = {
'first': first,
'pn': pn,
'kd':kd #这里取变量值,可以获取不同岗位的关键词
}
page = get_page(url, headers, data)
if page == None:
return None
max_pageNum = get_pageSize(page)
result = page['content']['positionResult']['result']
for num in range(0, max_pageNum):
positionId = result[num]['positionId']
positionId_list.append(positionId)
return positionId_list #该函数返回一个列表页的所有岗位的positionId
在获取到每个岗位的positionId后,我们就可以根据获取到的positionId进行拼接得到每个岗位详情页面的url,然后爬取这些url,来获取每个岗位的关键词(这里还有一个比较坑人的地方就是通过爬取来的网页内容和通过定位得到的内容竟然是不一样的,害的我纠结了好久),分析该网页如下图:具体的实现如下:
#获取每个岗位的职位要求
def get_content(positionId):
url = 'https://www.lagou.com/jobs/%s.html' %(positionId)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
'Referer': 'https://www.lagou.com/jobs/list_Python?px=default&city=%E5%8C%97%E4%BA%AC'
}
page = get_page(url,headers,data=0)
soup = Bs(page, 'html.parser')
content = soup.find('dd', class_='job_bt').get_text()
return content
接下来就是对获取到的岗位描述进行过滤处理,来获取英文关键词,实现如下:
#对获取的关键词列表进行过滤去重,获取top50的关键词
#处理岗位描述,获取英文关键词
def get_keyword(content):
pattern = re.compile('[a-zA-Z]+')
keyword = pattern.findall(content)
return keyword
然后,在通过collections中的Counter模块获取到这些英文关键词中的top50,实现如下:
#对获取的关键词列表进行过滤去重,获取top50的关键词
def parser_keyword(keyword_list):
for i in range(len(keyword_list)):
keyword_list[i] = keyword_list[i].lower()
keyword_top = Counter(keyword_list).most_common(50)
return keyword_top
最后把top50的关键词保存到Excel中,并且生成分析图,实现如下:
#数据保存到Excel中,并且生成报表。
def save_excel(keyword_top):
row = 1
col = 0
workbook = xlsxwriter.Workbook('lagou.xlsx')
worksheet = workbook.add_worksheet('lagou')
worksheet.write(0, col, u'关键词')
worksheet.write(0, col+1, u'频次')
for name, num in keyword_top:
worksheet.write(row, col, name)
worksheet.write(row, col+1, num)
row += 1
chart = workbook.add_chart({'type': 'area'})
chart.add_series({
'categories': 'lagou!$A$2:$A$51',
'values': 'lagou!$B$2:$B$51'
})
chart.set_title({'name': u'关键词排名'})
chart.set_x_axis({'name': u'关键词'})
chart.set_y_axis({'name': u'频次(/次)'})
worksheet.insert_chart('C2', chart, {'x_offset':15, 'y_offset':10})
workbook.close()
结果
具体生成的分析图如下:
如果对您有点帮助的话,麻烦您给点个赞,谢谢。
最后附上全部的代码:
# -*-coding: utf-8 -*-
import urllib2
import urllib
import re
from bs4 import BeautifulSoup as Bs
import json
import time
import sys
from collections import Counter
import xlsxwriter
kd = raw_input('请输入关键字:')
#获取页面内容
def get_page(url,headers,data):
if data == 0:
try:
request = urllib2.Request(url, headers=headers)
resp = urllib2.urlopen(request)
page = resp.read()
return page
except urllib2.URLError,e:
if hasattr('reason'):
print("爬取失败", e.reason)
sys.exit(1)
else:
try:
data = urllib.urlencode(data).encode('utf-8')
request = urllib2.Request(url, data=data, headers=headers)
resp = urllib2.urlopen(request)
page = json.loads(resp.read())
if page['success'] == True:
return page
else:
print(page['msg'])
return None
except urllib2.URLError,e:
print("爬取失败", e.reason)
#获取每一页最大的pageSize
def get_pageSize(page):
max_pageNum = page['content']['pageSize']
return max_pageNum
#获取每个岗位的职位要求
def get_content(positionId):
url = 'https://www.lagou.com/jobs/%s.html' %(positionId)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
'Referer': 'https://www.lagou.com/jobs/list_Python?px=default&city=%E5%8C%97%E4%BA%AC'
}
page = get_page(url,headers,data=0)
soup = Bs(page, 'html.parser')
content = soup.find('dd', class_='job_bt').get_text()
return content
#处理岗位描述,获取英文关键词
def get_keyword(content):
pattern = re.compile('[a-zA-Z]+')
keyword = pattern.findall(content)
return keyword
#获取每一页的岗位ID
def get_positionId(pn):
positionId_list = []
url = 'https://www.lagou.com/jobs/positionAjax.json?px=default&city=%E5%8C%97%E4%BA%AC&needAddtionalResult=false'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
'Referer': 'https://www.lagou.com/jobs/list_Python?px=default&city=%E5%8C%97%E4%BA%AC'
}
if pn == 1:
first = 'true'
else:
first = 'false'
data = {
'first': first,
'pn': pn,
'kd':kd
}
page = get_page(url, headers, data)
if page == None:
return None
max_pageNum = get_pageSize(page)
result = page['content']['positionResult']['result']
for num in range(0, max_pageNum):
positionId = result[num]['positionId']
positionId_list.append(positionId)
return positionId_list
#对获取的关键词列表进行过滤去重,获取top50的关键词
def parser_keyword(keyword_list):
for i in range(len(keyword_list)):
keyword_list[i] = keyword_list[i].lower()
keyword_top = Counter(keyword_list).most_common(50)
return keyword_top
#数据保存到Excel中,并且生成报表。
def save_excel(keyword_top):
row = 1
col = 0
workbook = xlsxwriter.Workbook('lagou.xlsx')
worksheet = workbook.add_worksheet('lagou')
worksheet.write(0, col, u'关键词')
worksheet.write(0, col+1, u'频次')
for name, num in keyword_top:
worksheet.write(row, col, name)
worksheet.write(row, col+1, num)
row += 1
chart = workbook.add_chart({'type': 'area'})
chart.add_series({
'categories': 'lagou!$A$2:$A$51',
'values': 'lagou!$B$2:$B$51'
})
chart.set_title({'name': u'关键词排名'})
chart.set_x_axis({'name': u'关键词'})
chart.set_y_axis({'name': u'频次(/次)'})
worksheet.insert_chart('C2', chart, {'x_offset':15, 'y_offset':10})
workbook.close()
#执行程序
def run():
#获取30页的数据
keyword_list = []
for pn in range(1, 2):
positionId_list= get_positionId(pn)
if positionId_list == None:
break
for positionId in positionId_list:
content = get_content(positionId)
keyword = get_keyword(content)
keyword_list += keyword
time.sleep(60)
keyword_top = parser_keyword(keyword_list)
save_excel(keyword_top)
if __name__ == '__main__':
run()
# save_excel()