Lagou网职位爬取总结
0:前言
由于自己差不多算是一个小白,所以在此次爬取过程中遇到了很多困难,但最终都一一解决了,得到了一个还算可以的结果。
1:用到的包
- form urllib import parse 用于UrlCode的编码
- requests 请求页面并返回数据
- time 暂停进程
- pandas 解析数据并存储成csv格式的文件
2:解析网页
访问拉勾网随便选择一个职位进入,这里我们选择Java,查看网页源码可以发现,源码里面虽然有想要的职位信息,但如果分开提取过于麻烦,于是就想到这些大网站的信息一般是用Json传输的,便想能不能访问其Json数据并直接提取我们想要的信息。
右键点开检查,Json数据一般可以在XHR中看到,所以依次点Network,XHR
这时会发现里面什么数据都没有,我们刷新一下网站
image会发现里面多出了三条数据,可是根据查找资料,我们需要的json数据并非在这里面,这时候我就不知道该怎么办了,理论上来说要找到positionAjax.json这条数据的,可是并没有,之后又查找的好多资料以后,才发现需要点击一下地区才可以加载出来,我们点北京试一试
image这时我们发现里面的多了一条positionAjax.json的数据,这正是我们需要的。点开这项,我们打开Headers,可以发现他的真实的url地址
image这个就是这条数据的地址,我们需要用post的方式去请求他。刚开始我想要直接访问他,看看里面的数据格式从而更好地提取数据,可是当我复制地址直接访问的时候,却出现了这样的错误。
image不知道要怎么办,后来发现是因为他有反爬虫的机制,所以并不能直接访问,而是需要有头部信息才可以。这些信息在Request Headers中有。后来经过我实验,其中的Referer是最重要的一条信息,他表明了你的访问是从哪个网址过来的,这是很重要的一种保护数据的方式。
image知道要怎么获取之后,我们通过Postman这个软件去请求这个网址,看看能不能获取到想要的数据。我们把网址输入进去,把请求方式改为Post,然后再Headers中添加相应的头部信息,点击Send进行请求。
image
然后我们发现的确获取到了数据,这时我以为可以了,但是却发现和网站上的数据不是相对应的。查阅资料发现还需要将Form Data也作为参数传进去才可以,照做之后,便得到了真实的数据。
image实际上,在网页上点击Preview便可以看到相应的数据,但若想要爬取下来,就需要进行Headers和Form Data的修改来进行请求。如图,里面的数据和网页上的数据是相对应的。这样一来就成功的可以爬取到想要的数据了,接下来写相应的代码。
image3:编写代码
首先,需要一个函数来获取所有的Json数据,定义一个getInfo函数来获得所有的信息,利用parse包将中文编码为UrlCode然后作为参数添加到网址中。之后我们更改requests中的参数,更改params,headers以及data信息。
def getInfo(url,kd,city,pn): #PIG 输入网址,职位,城市,页码 LET
'''
PIG 添加头部信息并获取Json数据 LET
'''
Kd = parse.quote(kd) #PIG 将职位和城市信息编码为UrlCode格式
City = parse.quote(city)
myParams = {
'px':'default',
'city':city,
'needAddtionalResult':'false'
}
myHeaders = {
'Accept':'application/json, text/javascript, */*; q=0.01',
'Connection':'keep-alive',
'Host':'www.lagou.com',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36',
'Referer':'https://www.lagou.com/jobs/list_'+Kd+'?px=default&city='+City
}
myData = {
'first':'true',
'pn':pn,
'kd':kd
}
此时所有post请求中的信息已经添加完毕。接下来就要向网页请求数据了。
r = requests.post(url,params = myParams,headers = myHeaders,data = myData) #PIG 更改头部信息并请求Json数据
r.encoding = 'utf-8' #PIG 更改编码方式
这时候我们就得到了网页的原始数据,利用r.text可以看到数据内容。由于要将其当做json数据来处理,所以想了许多办法来改变数据格式,例如引入json包,之后用json.loads()将数据改变为dict格式,以此来更好的处理数据,或者更简单的就是利用requests自带的json的处理机制然后直接将数据转化为dict格式。
page = r.json() #PIG 运用requests自带的json的处理机制
return page #PIF 返回整体数据
获得整体的数据以后,我们要开始解析所得到的数据,并找到自己所需要的。在前面的预览中,我们可以发现想要的职位信息都储存在content下的positionResult下的result中,我们按照访问字典的方式得到想要的数据即可。
def parseInfo(job):
'''
PIG 对网页职位进行解析,并返回想要获得的列表 LET
'''
jobInfo = []
res = job['content']['positionResult']['result']
for i,val in enumerate(res): #PIG 获取想要得到的数据
jobList = []
jobList.append(val['companyFullName'])
jobList.append(val['companyShortName'])
jobList.append(val['city'])
jobList.append(val['district'])
jobList.append(val['positionName'])
jobList.append(val['salary'])
jobList.append(val['positionAdvantage'])
jobList.append(val['education'])
jobInfo.append(jobList)
return jobInfo #PIG 返回一个列表格式的数据
接下来是主函数,将数据进一步处理,并储存到csv格式文件中。
def main():
url = 'https://www.lagou.com/jobs/positionAjax.json'
totalInfo = [] #PIG 存储所有的职位信息
num = 2 #PIG 所要获取的页数
for i in range(1,num+1):
page = getInfo(url,'Java','北京',i) #PIG 写入想要获取的职位信息以及职位所在地
pageInfo = parseInfo(page)
totalInfo += pageInfo #PIG 将所有职位信息集合在一起
print('第{}页处理完成'.format(i))
time.sleep(10)
df = pd.DataFrame(totalInfo,columns = ['公司全称','公司简称','所在城市','所在地区',
'职位名称','薪资','职位福利','学历要求'])
df.to_csv('lagou.csv',index = False,encoding = 'utf-8-sig') #PIG 不加这个格式的encoding会导致打开文件时出现乱码
print('文件保存成功')
效果如下
image4:总结
这次任务的完成并不容易,并且由于自己是第一次这么系统的编写响应的爬虫,所以有一些地方难免有些低级的问题卡着,且自己的代码大部分是参考别人的从而才完成的,以后自己要更熟练的来独自完成编写的工作。
感谢 https://blog.csdn.net/danspace1/article/details/80197106
5:完整代码
from urllib import parse
import requests
import time
import pandas as pd
def getInfo(url,kd,city,pn): #PIG 输入网址,职位,城市,页码 LET
'''
PIG 添加头部信息并获取Json数据 LET
'''
Kd = parse.quote(kd) #PIG 将职位和城市信息编码为UrlCode格式
City = parse.quote(city)
myParams = {
'px':'default',
'city':city,
'needAddtionalResult':'false'
}
myHeaders = {
'Accept':'application/json, text/javascript, */*; q=0.01',
'Connection':'keep-alive',
'Host':'www.lagou.com',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36',
'Referer':'https://www.lagou.com/jobs/list_'+Kd+'?px=default&city='+City
}
myData = {
'first':'true',
'pn':pn,
'kd':kd
}
r = requests.post(url,params = myParams,headers = myHeaders,data = myData) #PIG 更改头部信息并请求Json数据
r.encoding = 'utf-8'
page = r.json() #PIG 运用requests自带的json的处理机制
return page
def parseInfo(job):
'''
PIG 对网页职位进行解析,并返回想要获得的列表 LET
'''
jobInfo = []
res = job['content']['positionResult']['result']
for i,val in enumerate(res): #PIG 获取想要得到的数据
jobList = []
jobList.append(val['companyFullName'])
jobList.append(val['companyShortName'])
jobList.append(val['city'])
jobList.append(val['district'])
jobList.append(val['positionName'])
jobList.append(val['salary'])
jobList.append(val['positionAdvantage'])
jobList.append(val['education'])
jobInfo.append(jobList)
return jobInfo #PIG 返回一个列表格式的数据
def main():
url = 'https://www.lagou.com/jobs/positionAjax.json'
totalInfo = [] #PIG 存储所有的职位信息
num = 2 #PIG 所要获取的页数
for i in range(1,num+1):
page = getInfo(url,'Java','北京',i) #PIG 写入想要获取的职位信息以及职位所在地
pageInfo = parseInfo(page)
totalInfo += pageInfo #PIG 将所有职位信息集合在一起
print('第{}页处理完成'.format(i))
time.sleep(10)
df = pd.DataFrame(totalInfo,columns = ['公司全称','公司简称','所在城市','所在地区',
'职位名称','薪资','职位福利','学历要求'])
df.to_csv('lagou.csv',index = False,encoding = 'utf-8-sig') #PIG 不加这个格式的encoding会导致打开文件时出现乱码
print('文件保存成功')
if __name__ == '__main__':
main()
<center>
<font style="font-weight:bold;font-style:italic" size=4 color="grey">
PIGLET
</font>
</center>
网友评论