excel抓取网页动态数据(Python3.6、Pycharm输入关键字Python操作Excel模板(图))
优采云 发布时间: 2022-01-16 07:09excel抓取网页动态数据(Python3.6、Pycharm输入关键字Python操作Excel模板(图))
运行环境:Python 3.6、Pycharm 2017.2.3、Chrome 61.0.3163.100
前言
刚刚接触到异步取数据,所以试试如何实现异步取数据。
这次需要实现的是在招聘网站 [网站link]中爬出一些Python相关职位的基本信息,并将这些基本信息保存到Excel表格中。
开始动手分析网页需要的一些知识点
打开拉勾网首页后,我们在搜索框中输入关键字Python,即可找到与Python相关的工作。在搜索结果页面中,我们可以按照以下顺序进行查找。
–> 右键检查
--> 打开检查元素后默认打开元素
–> 我们切换到网络选项卡,刷新网页,就会有各种条目的请求
--> 因为网站是异步请求,所以在Network中打开XHR,分析JSON中的数据。
# 该页面的请求url
Request URL:https://www.lagou.com/jobs/positionAjax.json?city=%E5%B9%BF%E5%B7%9E&needAddtionalResult=false&isSchoolJob=0
# 该页面的请求方法
Request Method:POST
--------------------------------
# Request Headers中的相关信息
包括Cookie、Referer、User-Agent等我们之后会用到的信息
代码片段 1 - 请求网页
import requests # 导入请求模块
def getJobList():
res = requests.post(
# 请求url
url='https://www.lagou.com/jobs/positionAjax.json?px=default&city=%E5%B9%BF%E5%B7%9E&needAddtionalResult=false&isSchoolJob=1'
)
result = res.json() # 获取res中的json信息
print(result)
getJobList()
运行结果:
{'success': False, 'msg': '您操作太频繁,请稍后再访问', 'clientIp': '113.14.1.254'}
出现这样的结果,应该是hook网络的反爬机制发挥了作用,所以这时候需要伪装成用户访问,并且需要添加headers信息。
代码片段 2 - 添加标头信息
import requests
headers = {
# User-Agent(UA) 服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。也就是说伪装成浏览器进行访问
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
# 用于告诉服务器我是从哪个页面链接过来的,服务器基此可以获得一些信息用于处理。如果不加入,服务器可能依旧会判断为非法请求
'Referer': 'https://www.lagou.com/jobs/list_Python?px=default&gx=&isSchoolJob=1&city=%E5%B9%BF%E5%B7%9E'
}
def getJobList():
res = requests.post(
url='https://www.lagou.com/jobs/positionAjax.json?px=default&city=%E5%B9%BF%E5%B7%9E&needAddtionalResult=false&isSchoolJob=1',
headers = headers
)
result = res.json()
print(result)
getJobList()
运行结果:
{'success': True, 'requestId': None, 'resubmitToken': None, 'msg': None, 'content': {'pageNo': 1, 'pageSize': 15, 'hrInfoMap': {'1859069': {'userId': 1617639, 'positionName': None, 'phone': None, 'receiveEmail': None, 'realName': 'tracy_cui', 'portrait': None, 'canTalk': True, 'userLevel': 'G1'}, '3667315': {'userId': 8290676, 'positionName': '', 'phone': None, 'receiveEmail': None, 'realName': 'HR', 'portrait': 'i/image/M00/61/32/CgpEMlmSrOWAUE1OAAJ4d6lfWh8386.png', 'canTalk': True, 'userLevel': 'G1'}, '3279531': {'userId': 403820, 'positionName': 'hr', 'phone': None, 'receiveEmail': None, 'realName': '马*敏*感*词*', 'portrait': 'image1/M00/11/C7/Cgo8PFUBXCeAdWuwAABDv40Fxsc038.png', 'canTalk': True, 'userLevel': 'G1'}, '3475945': {'userId': 701585, 'positionName': 'HR', 'phone': None, 'receiveEmail': None, 'realName': '赵敏', ...................}
这样就得到了响应结果中的json信息,与Preview中的数据信息一致(dict类型的顺序可能不一致)。
代码片段 3 - 获取当前页面作业信息
可以发现需要的职位信息在content->positionResult->result下,里面收录了工作地点、公司名称、职位等信息。
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
'Referer': 'https://www.lagou.com/jobs/list_Python?px=default&gx=&isSchoolJob=1&city=%E5%B9%BF%E5%B7%9E'
}
def getJobList():
res = requests.post(
url='https://www.lagou.com/jobs/positionAjax.json?px=default&city=%E5%B9%BF%E5%B7%9E&needAddtionalResult=false&isSchoolJob=1',
headers = headers
)
result = res.json()
jobsInfo = result['content']['positionResult']['result'] # 输出返回的整个json信息中的职位相关信息
print(type(jobsInfo)) # 我们查看一下jobsInfo的数据类型
print(jobsInfo) # 打印职位信息
getJobList()
运行结果:
[{'companyId': 54727, 'positionId': 3685814, 'industryField': '移动互联网', 'education': '本科', 'workYear': '应届毕业生', 'city': '广州', 'positionAdvantage': '带薪年假;五险一金;节日福利;年度体检', 'createTime': '2017-10-11 10:31:52', 'salary': '4k-8k', 'positionName': '电商运营', 'companySize': '150-500人', 'companyShortName': '有车以后', 'companyLogo': 'image1/M00/3A/2D/Cgo8PFWsrUeAf1gEAAF2eIhOLlo086.jpg', 'financeStage': '成熟型(C轮)', 'jobNature': '全职', 'approve': 1, 'companyLabelList': ['股票期权', '带薪年假', '年度旅游', '弹性工作'], 'district': None, 'positionLables': [], 'industryLables': [], 'publisherId': 6331287, 'businessZones': None, 'score': 0, 'companyFullName': '广州市有车以后信息科技*敏*感*词*', 'adWord': 0, 'imState': 'disabled', 'lastLogin': 1507686331000, 'explain': None, 'plus': None, 'pcShow': 0, 'appShow': 0, 'deliver': 0, 'gradeDescription': None, 'promotionScoreExplain': None, 'firstType': '运营/编辑/客服', ...................
根据运行结果发现,jobsInfo中的数据类型是一个列表,其中收录了整个页面显示的所有职位的信息。因此,可以采用遍历的方法,对每个职位的相关信息进行梳理,提取出需要的数据,如公司名称、职位优势等。
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
'Referer': 'https://www.lagou.com/jobs/list_Python?px=default&gx=&isSchoolJob=1&city=%E5%B9%BF%E5%B7%9E'
}
def getJobList():
res = requests.post(
url='https://www.lagou.com/jobs/positionAjax.json?px=default&city=%E5%B9%BF%E5%B7%9E&needAddtionalResult=false&isSchoolJob=1',
headers = headers
)
result = res.json()
jobsInfo = result['content']['positionResult']['result']
return jobsInfo
for job in getJobList():
# 这里演示,提取出公司名以及公司职位优势
print(job['companyFullName'] + ':' + job['positionAdvantage'])
运行结果后,剩下的相关信息可以根据key值自行获取:
广州市暨嘉信息科技*敏*感*词*:岗位培训,销售技巧,智能工业,机械设备
广州云乐数码科技*敏*感*词*:工作气氛好,学习机会多,生长快,工作环境好
广州市贝聊信息科技*敏*感*词*:愉快的工作氛围,下午茶,弹性上班
广州元创信息科技*敏*感*词*:交通便利,双休
广州数沃信息科技*敏*感*词*:技术强大,五险一金,周末双休,带薪年假
..................
最终代码 - 写入 Excel
Python中Excel的模板读写主要有xlrd、xlwt、xlutils、openpyxl、xlsxwriter。这里使用的是xlsxWriter,可以参考我之前的博客【链接】
import requests
import xlsxwriter
import time
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
'Referer': 'https://www.lagou.com/jobs/list_Python?px=default&gx=&isSchoolJob=1&city=%E5%B9%BF%E5%B7%9E',
'Cookie': 'user_trace_token=20171010203203-04dbd95d-adb7-11e7-946a-5254005c3644; LGUID=20171010203203-04dbddae-adb7-11e7-946a-5254005c3644; index_location_city=%E5%B9%BF%E5%B7%9E; JSESSIONID=ABAAABAABEEAAJA8BF3AD5C8CFD40070BD3A86E50B0F9E4; PRE_UTM=; PRE_HOST=; PRE_SITE=https%3A%2F%2Fwww.lagou.com%2F; PRE_LAND=https%3A%2F%2Fwww.lagou.com%2Fjobs%2Flist_Python%3FlabelWords%3D%26fromSearch%3Dtrue%26suginput%3D; TG-TRACK-CODE=index_navigation; SEARCH_ID=0cc609743ac*敏*感*词*bf18789b584210f6ccb; _gid=GA1.2.271865682.1507638722; Hm_lvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1507638723; Hm_lpvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1507720548; _ga=GA1.2.577848458.1507638722; LGSID=20171011190218-a611d705-ae73-11e7-8a7a-525400f775ce; LGRID=20171011191547-882eafd3-ae75-11e7-8a92-525400f775ce'
}
def getJobList(page):
formData = {
'first': 'false',
'pn': page,
'kd': 'Python'
}
res = requests.post(
# 请求的url
url='https://www.lagou.com/jobs/positionAjax.json?city=%E5%B9%BF%E5%B7%9E&needAddtionalResult=false&isSchoolJob=0',
# 添加headers信息
headers=headers
)
result = res.json()
jobsInfo = result['content']['positionResult']['result']
return jobsInfo
# 创建一个excel表格
workbook = xlsxwriter.Workbook('Python职位信息.xlsx')
# 为创建的excel表格添加一个工作表
worksheet = workbook.add_worksheet()
# 将数据写入工作表中
def writeExcel(row=0, positionName='职位名', city='工作地点', education='教育程度', salary='薪资', companyFullName='公司名字'):
if row == 0:
worksheet.write(row, 0, positionName)
worksheet.write(row, 1, salary)
worksheet.write(row, 2, city)
worksheet.write(row, 3, education)
worksheet.write(row, 4, companyFullName)
else:
worksheet.write(row, 0, job['positionName'])
worksheet.write(row, 1, job['salary'])
worksheet.write(row, 2, job['city'])
worksheet.write(row, 3, job['education'])
worksheet.write(row, 4, job['companyFullName'])
# 在第一行中写入列名
writeExcel(row=0)
# 从第二行开始写入数据
row = 1
# 这里爬取前五页招聘信息做一个示范
for page in range(1, 6):
# 爬取一页中的每一条招聘信息
for job in getJobList(page=page):
# 将爬取到的信息写入表格中
writeExcel(row=row, positionName=job['positionName'], companyFullName=job['companyFullName'], city=job['city'],
education=job['education'], salary=job['salary'])
row += 1
print('第 %d 页已经爬取完成' % page)
# 做适当的延时,所谓不做延时的爬虫都是耍流氓
time.sleep(0.5)
# 关闭表格文件
workbook.close()
运行结果:
这样,我们就爬下了我们需要的招聘信息。
总结