python抓取网站职位信息代码及解析
第一次写一篇博客,最近不是想找份数据分析相关的工作嘛,大学时候学计算机,要毕业那一段实习去了内审内控,没有实习计算机相关(不过以前实习过学校安排的),后面找工作就超级难,我这个人以前在学校就爱瞎折腾,搞了个表白墙学校大概几千人关注后来卖给学院部门了哈哈哈哈,也喜欢写写东西,现在在携程做sql相关的活(有点无聊),在这里先奉劝各位在校的同学记得一定多写代码,写写Blog。
言归正传,博主用的是 Anaconda里的spyder
抓取数据的目标网站是拉勾网https://www.lagou.com/,首先输入自己想找的工作内容,按F12打开对应开发人员工具,F5刷新下界面,点击对应的xhr和js看相关传输数据(ajax看xhr,ajax界面无需重新加载整个网页的情况下,能够更新部分网页的技术,数据传输会减少,所以用的还是多的,呜呜呜以前还写过工作后都用不到了),可以看到下图的positionAjax.json
里面的数据就是我们想要的薪资以及对应公司的信息,复制该json文件链接地址
https://www.lagou.com/jobs/positionAjax.json?city=%E6%B7%B1%E5%9C%B3&needAddtionalResult=false后续我们从这里爬取对应数据
我们继续下拉这个js数据,看看他如何进行对应页码的数据获取,可以看到FORM_DATA 这个数据有我们要的相关信息(手动输入在搜索栏里的 kd:数据分析 页码对应Pn:1 first:true),我们接着进行验证可以点击第二页继续查看,发现对应只是Pn+1,因此可以写出对应的代码
headers = {
'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36',# 自己百度下什么型号用着爽用什么型号
'Host':'www.lagou.com',# 首页名
'Referer':'https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90'
} # 请求头,URL中设置了城市名
form_data = {'first':'true','pn':num,'kd':'数据分析'} # 网页From Data参数
因为现在的网页都会写一些反爬虫功能(我print(r.json())后发现控制台弹出网页请求繁忙,以前写JAVA都练习过Cookies吧,emmmm没cookies访问太多次被拉黑了呗),所以大多都是要写cookies的,不同网页自己定义的Cookies不同,因此我们需要获取网站的Cookies,获取Cookies
cookie_url = "https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90"
session = requests.Session()
session.get(url=cookie_url, headers=headers)
cookies_new=session.cookies#获取网站cookies
把单页js进行解析,(网上百度下Js在线解析复制js内容进去),可以在获取json的地方改下代码即可(print直接控制台显示复制不方便,直接txt保存到本地了)
import requests
import math
import pandas as pd
import time
import json
def get_json(url, num): # 获取JSON,获取第几页数据
headers = {
'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36',
'Host':'www.lagou.com',
'Referer':'https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90'
} # 请求头,URL中设置了城市名
form_data = {'first':'true','pn':num,'kd':'数据分析'} # 网页From Data参数
cookie_url = "https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90"
session = requests.Session()
session.get(url=cookie_url, headers=headers)
cookies_new=session.cookies#获取网站cookies
try:
r=requests.post(url, headers=headers, data=form_data,cookies=cookies_new) # 抓取职位信息的JOIN文件
r.raise_for_status()
r.encoding = 'utf-8'
#print(r.json()) #测试是否成功获取网页
with open(r"C:\Users\xxp\.spyder-py3\testcode\tmp.txt", "w") as fp:
fp.write(json.dumps(r.json(),indent=4,ensure_ascii=False)) # txt
return r.json()
except:
return 'false'
if __name__=='__main__':
get_json("https://www.lagou.com/jobs/positionAjax.json?city=%E6%B7%B1%E5%9C%B3&needAddtionalResult=false",1)
根据相应json的元素进行编写,
def get_a_page(result): # 获取一页的信息
field = ['companyFullName','companyShortName','createTime','companySize','financeStage','district','positionName',
'firstType','secondType','thirdType','industryField','positionLables','skillLables','jobNature',
'resumeProcessDay','workYear','education','salary','positionAdvantage'] # 要获取哪些字段信息
page_info = []
try:
for i in result:
info = []
[info.append(i[j]) for j in field]
page_info.append(info)
return page_info
except:
return ''
def get_pages(count):
num = math.ceil(count/15)
if num >= 0:
return num #爬取所有页
else:
return num
我们来整理下思路,获取界面对应json的数据,下一步思考进行多个界面信息获取该如何操作爬取,最后进行数据的整合输出
最后我们的代码整合如下:
import requests
import math
import pandas as pd
import time
import json
def get_json(url, num): # 获取JSON,获取第几页数据
headers = {
'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36',
'Host':'www.lagou.com',
'Referer':'https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90'
} # 请求头,URL中设置了城市名
form_data = {'first':'true','pn':num,'kd':'数据分析'} # 网页From Data参数
cookie_url = "https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90"
session = requests.Session()
session.get(url=cookie_url, headers=headers)
cookies_new=session.cookies#获取网站cookies
try:
r=requests.post(url, headers=headers, data=form_data,cookies=cookies_new) # 抓取职位信息的JOIN文件
r.raise_for_status()
r.encoding = 'utf-8'
#print(r.json())
#with open(r"C:\Users\xxp\.spyder-py3\testcode\tmp.txt", "w") as fp:
#fp.write(json.dumps(r.json(),indent=4,ensure_ascii=False)) # txt测试是否成功获取网页
return r.json()
except:
return 'false'
def get_a_page(result): # 获取一页的信息
field = ['companyFullName','companyShortName','createTime','companySize','financeStage','district','positionName',
'firstType','secondType','thirdType','industryField','positionLables','skillLables','jobNature',
'resumeProcessDay','workYear','education','salary','positionAdvantage'] # 要获取哪些字段信息
page_info = []
try:
for i in result:
info = []
[info.append(i[j]) for j in field]
page_info.append(info)
return page_info
except:
return ''
def get_pages(count):
num = math.ceil(count/15)
if num >= 0:
return num #爬取所有页
else:
return num
def main():
url = 'https://www.lagou.com/jobs/positionAjax.json?city=%E6%B7%B1%E5%9C%B3&needAddtionalResult=false'
page_1 = get_json(url, 1) # 总职位数在每页的json字典中都有显示,这里随便选了第一页
total_count = page_1['content']['positionResult']['totalCount']
num=get_pages(total_count)
total_info=[]
print('职位总数:{},页数:{}'.format(total_count, num))
start= time.time()
time.sleep(20)
for n in range(1, num+1): # 获取每页的json,汇总数据,转成一个嵌套列表,每个子列表为一个职位的所有信息
page=get_json(url, n)
result = page['content']['positionResult']['result']#对应职位信息 后续统计个数
a_page_info = get_a_page(result)#获取对应json数据个数
total_info += a_page_info#每页职位相加
print('已经抓取第{}页,职位总数:{},当前总耗时{:.2f}秒'.format(n, str(len(total_info)), time.time()-start))
time.sleep(10)# 暂停10秒,防止被服务器拉黑
# 把list转为DataFrame
df=pd.DataFrame(data=total_info,columns=['公司全名','公司简称','创办时间','公司规模','融资阶段','区域','职位名称',
'岗位类型1级','岗位类型2级','岗位类型3级','行业领域','职位标签','技能标签','工作形式',
'简历处理时间','工作经验','学历要求','工资','职位福利'])
df.to_csv(r'C:\Users\xxp\.spyder-py3\testcode\lagou_job.csv',index=False,encoding='utf_8_sig')#注意utf_8_sig 否则中文乱码
print('CSV保存成功')
if __name__=='__main__':
main()
当然我们也可以对数据在python直接进行图表化输出,不过个人喜好tableau(以前做内审用tableau美观很多),也有些公司自己会开发些数据可视化软件,不同公司不同工具。
第一次写Blog,有什么不懂可以留言,python也是上个月刚开始接触开始自学,和以前自学写android一样,不过Android自学满满的痛苦,毕设Android本来要给老师拿去写个报告,后来工作太忙不了了之了,不过写的其实挺差的 代码也没那么规范,毕竟没有去实际工作还是硬伤,在校的同学们一定要注重实习和比赛啊!!