Python3网络爬虫之requests动态爬虫:拉钩网
操作环境: Windows10、Python3.6、Pycharm、谷歌浏览器
目标网址: https://www.lagou.com/jobs/list_Python/p-city_0?px=default (拉钩Python职位)
很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:101677771
爬虫目录
- 1、项目疑惑
- 2、分析网页
- 2.1、POST请求
- 2.2、参数解析
- 2.3、详情页分析
- 3、解决请求
- 3.1、请求数据
- 3.2、解决反爬
- 4、翻页
- 4.1、for循环翻页
- 4.2、while循环翻页
- 5、存入Excel
- 5.1、Excel表头
- 5.2、保存函数
- 六、项目总结
- 6.1、填充问题
- 6.2、汉字职位填充问题
1、项目疑惑
拉钩爬虫区别于许多网站的反爬机制,即使请求头参数以及请求体参数加齐也无法请求返回正确数据,若返回 “您操作太频繁,请稍后再访问” 字眼,则表示被拉钩反爬机制识别你的不是正常浏览网页,而是爬虫程序请求。
{"status":false,"msg":"您操作太频繁,请稍后再访问","clientIp":"223.104.65.43","state":2402}
2、分析网页
本次项目与上次腾讯爬虫一样属于ajax加载的动态数据,但是他与腾讯招聘不同的是,列表页是ajax加载数据,而详情页却是静态数据,腾讯招聘则是经典的双ajax加载数据页面。
所以本次项目只为了解决反爬机制与爬取列表页数据即可,下次小编再带大家写一篇动静结合的爬虫项目,敬请期待。话不多说,开始进入正题!
2.1、POST请求
requests模块发送post请求时,提交的是data参数,但data表单参数不会在接口链接上显示,这与之get请求的params参数相反。
2.2、参数解析
px参数: 工作地点,爬取指定地点的岗位信息。
pn参数: 翻页页数。
kd参数: 职位名,爬取指定岗位名称的相关信息。
2.3、详情页分析
虽说此次不请求详情页里的数据,但还是帮其他有需要的小伙伴解析一波。
因为详情页为静态数据,所以我们直接分析它的链接即可。从岗位详情页链接可看出两个重要参数:职位特有id与show参数。
通过分析列表页的json数据发现岗位特有id与show参数均在里面。
从下图可看出岗位特有id是固定不变的,然而show参数却是每次请求将变换,会更新,不固定。但无关系,直接从请求的列表页中获取即可,即请求即获取。
3、解决请求
3.1、请求数据
分析好网页,开始写程序代码,首先导入需要的库以及设置请求头伪造身份,而post请求需要用到的data参数需要重复使用到,则定义一个from_data函数构建data参数,以便调用它。
# 导入需要的库
import requests
import json
import parsel
import openpyxl
import reheaders = { # 请求头,伪造身份'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36',
}'''构建data表单'''
def from_data(kd,pn):json_data = {'first': 'false','pn': str(pn), # 页数'kd': kd # 职位名}return json_data'''请求数据'''
def get_data(json_url):data = from_data('python','1')# 获取表单数据# 请求接口链接response = requests.post(url=json_url,headers=headers,data=data)print(response.text)if __name__ == '__main__':# json接口链接json_url = 'https://www.lagou.com/jobs/positionAjax.json?city=%E5%B9%BF%E5%B7%9E&needAddtionalResult=false'get_data(json_url) # 获取数据
3.2、解决反爬
cookie_headers = { # cookie请求头,伪造身份'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36','referer':'https://www.lagou.com/jobs/list_Python/p-city_213?&cl=false&fromSearch=true&labelWords=&suginput='
}
json_headers = { # json数据请求头'Host': 'www.lagou.com',"origin": "https://www.lagou.com","referer": "referer: https://www.lagou.com/jobs/list_Python/p-city_0?&cl=false&fromSearch=true&labelWords=&suginput=","user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36",
}'''请求cookies值'''
def get_cookies(cookies_url):# allow_redirects重定向response = requests.get(url=cookies_url, headers=headers, allow_redirects=False)cookies = response.cookies # get请求获取cookies值return cookies'''请求数据'''
def get_data(json_url):# for pn in range(1,3,1):# 搜索关键字链接cookies_url = 'https://www.lagou.com/jobs/list_Python/p-city_0?&cl=false&fromSearch=true&labelWords=&suginput='cookies = get_cookies(cookies_url) # 获取cookiejson_data = from_data('1','Python') # 获取表单数据# 请求接口链接response = requests.post(url=json_url,headers=json_headers,cookies=cookies,data=json_data)print(response.text)
这里测试一页,输出结果中有Python的职位名,获取的数据无误,反爬解决成功!
4、翻页
4.1、for循环翻页
for循环翻页即手动设置翻页页数,这样只适合单个职位爬取方式,简单有效。
for pn in range(1,10,1): # for循环翻页# 搜索关键字链接cookies_url = 'https://www.lagou.com/jobs/list_Python/p-city_0?&cl=false&fromSearch=true&labelWords=&suginput='cookies = get_cookies(cookies_url) # 获取cookiejson_data = from_data(str(pn),'Python') # 获取表单数据# 请求接口链接response = requests.post(url=json_url,headers=json_headers,cookies=cookies,data=json_data)print(len(response.text))
4.2、while循环翻页
自定义每页总的职位数量,while True无限循环,每循环一次加每页总的职位数量,直到自定义的职位数量大于获取到的总职位量,便结束循环、结束翻页。
提取相关的职位字段数据。
replace:替换
‘’.join():合并
'''请求数据'''
def get_data(json_url):data_list = [] # 定义一个空列表,用于填充获取到的字段数据pn = 15while True:# 搜索关键字链接cookies_url = 'https://www.lagou.com/jobs/list_Python/p-city_0?&cl=false&fromSearch=true&labelWords=&suginput='cookies = get_cookies(cookies_url) # 获取cookiejson_data = from_data(int(pn / 15),'Python') # 获取表单数据# 请求接口链接response = requests.post(url=json_url,headers=json_headers,cookies=cookies,data=json_data)results = response.json()['content']['positionResult']['result']for result in results:id = result['positionId'] # idpositionName = result['positionName'] # 职位名称city = result['city'] # 城市companyFullName = result['companyFullName'] # 公司名称pub_time = result['createTime'] # 发布时间education = result['education'] # 学历firstType = result['firstType'] # 职位类型firstType = firstType.replace('|', '-')salary = result['salary'] # 薪资workYear = result['workYear'] # 工作经验companySize = result['companySize'] # 公司规模skillLables = result['skillLables'] # 学识要求skillLables = '-'.join(skillLables)companyLabelList = '-'.join(result['companyLabelList']) # 公司福利# 输出获取到的字段数据print(id, positionName, city, companyFullName, pub_time, education,firstType, salary, workYear, companySize, skillLables, companyLabelList)data_list.append([id, positionName, city, companyFullName, pub_time, education,firstType, salary, workYear, companySize, skillLables, companyLabelList])pn += 15 # 每循环一次增加一页if pn > response.json()['content']['positionResult']['totalCount'] + 15:break # 超过总职位数便结束循环return data_list
5、存入Excel
存excel表格需要用到openpyxl,import openpyxl导入,下载即pip install openpyxl
5.1、Excel表头
openpyxl.Workbook(): 创建一个excel薄
create_sheet(): 选择簿名
cell: 操作某行某列的某个值
row: 行
column: 列
value: 值
# 创建一个excel薄wb = openpyxl.Workbook()sheet1 = wb.create_sheet('position')# 写入excel表头sheet1.cell(row=1, column=1, value='id')sheet1.cell(row=1, column=2, value='职位名称')sheet1.cell(row=1, column=3).value = '城市'sheet1.cell(row=1, column=4).value = '公司名称'sheet1.cell(row=1, column=5).value = '发布时间'sheet1.cell(row=1, column=6).value = '学历'sheet1.cell(row=1, column=7).value = '职位类型'sheet1.cell(row=1, column=8).value = '薪资'sheet1.cell(row=1, column=9).value = '工作经验'sheet1.cell(row=1, column=10).value = '公司规模'sheet1.cell(row=1, column=11).value = '职位要求'sheet1.cell(row=1, column=12).value = '公司福利'wb.save('拉勾招聘岗位信息.xlsx')
5.2、保存函数
定义一个save_excel函数用于将数据存入Excel表格。
data_list:数据列表
'''保存为excel文件'''
def save_excel(data_list):wb = openpyxl.load_workbook('拉勾招聘岗位信息.xlsx')sheet = wb['position']for d in data_list:sheet.append(d) # 写入数据wb.save('拉勾招聘岗位信息.xlsx') # 保存
六、项目总结
本次项目只爬取了一个Python职位信息,若想继续爬取更多的职位信息,可以定义一个职位列表,将需要爬取的职位名写入其中即可。
6.1、填充问题
6.2、汉字职位填充问题
转化为前端适合的编码格式,需要用到urllib内置库里的parse函数,直接导入即可import urllib.parse 。
import urllib.parsekd = '数据分析'
position_html = urllib.parse.quote(kd)
print('转化为前端适合的编码格式:',position_html)
# 执行position_html结果为:转化为前端适合的编码格式: %E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90position = urllib.parse.unquote(position_html)
print('转化为Python程序适合的编码:',position)
# 执行position结果为:转化为Python程序适合的编码: 数据分析
如代码所示,链接填充用position_html即可,若data表单里的kd职位名参数用position即可。
Python3网络爬虫之requests动态爬虫:拉钩网相关推荐
- chromedp网络监听_动态爬虫三:监听网络事件 + 监听js事件
一: 概述 上两篇文章介绍了cdp协议和chromedp库,从这篇文章开始动手实战一下,我们要拿到页面上更多的网络请求,最直接的想法就是类似于开发者工具里的network,只有一有网络请求就显示在列表 ...
- scrapy爬虫实践之抓取拉钩网招聘信息(4)
拉勾的302搞的我不心力憔悴,几乎失去了动力继续再研究拉勾爬虫-实际上,这种无力感很大程度上来源于知识结构的匮乏(尤其是基础方面)和毫无进展带来的挫败感. 于是乎去读基础教程<learning ...
- python爬虫如何配置动态爬虫代理
很多网站会检测某一段时间某个IP的访问次数(通过流量统计,系统日志等),如果访问次数多的不像正常人,它会禁止这个IP的访问. 所以我们可以设置一些代理服务器,每隔一段时间换一个代理,就算IP被禁止,依 ...
- python爬虫解决频繁访问_python3拉钩网爬虫之(您操作太频繁,请稍后访问)
你是否经历过这个: 那就对了~ 因为需要post和相关的cookie来请求~ 所以,一个简单的代码爬拉钩~~~ import requests import time import json def ...
- scrapy爬虫实践之抓取拉钩网招聘信息(2)
今天遇到了一个百思不得其解的问题.我用xpath获取目标网页的divs,理论上来说,应该是把这个div下的所有div存进了列表里,但是语句却是这样写的 divs = response.xpath('/ ...
- Python3网络爬虫1:初识Scrapy
转载出处:https://blog.csdn.net/c406495762/article/details/72858983 官方:https://scrapy-chs.readthedocs.io/ ...
- 《Python3网络爬虫开发实战(第二版)》内容介绍
这是「进击的Coder」的第 505 篇分享 作者:崔庆才 大家好,本节首先来预告下即将出版的<Python3网络爬虫开发实战(第二版)>的主要内容. 由于我已经把书的总体的内容介绍写在了 ...
- 【Python3网络爬虫开发实战】4-解析库的使用-3 使用pyquery
在上一节中,我们介绍了Beautiful Soup的用法,它是一个非常强大的网页解析库,你是否觉得它的一些方法用起来有点不适应?有没有觉得它的CSS选择器的功能没有那么强大? 如果你对Web有所涉及, ...
- python3 爬虫实例_【实战练习】Python3网络爬虫快速入门实战解析(上)
原标题:[实战练习]Python3网络爬虫快速入门实战解析(上) 摘要 使用python3学习网络爬虫,快速入门静态网站爬取和动态网站爬取 [ 前言 ] 强烈建议:请在电脑的陪同下,阅读本文.本文以实 ...
最新文章
- 万字总结 MySQL核心知识,赠送25连环炮
- 大数据学习笔记二:Ubuntu/Debian 下安装大数据框架Hadoop
- python 日期格式和字符串格式的转化
- react的bind(this)
- Linux环境下安装jenkins
- selenium webdirver之rdoc使用
- 导出excel数字前面的0消失_EXCEL文本之王TEXT函数的4个运用
- attr与prop的区别
- JBox2D手机游戏引擎介绍(附jbox2d官网网址)
- Linux内核生成版本号的一些研究
- hystrix 源码 线程池隔离_“池”的思想:从java线程池到数据库连接池的源码解读(1)...
- 用EasyRecovery“监控硬盘”功能检测硬盘问题的方法
- PHP下ajax跨域的解决方案之window.name
- 男人的爱只有一次----女孩你珍惜了吗
- Python实战之路-day6
- 常用于页面交互的JavaScript的一些技巧分析
- 老李推荐:第6章2节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-获取命令字串...
- pyCharm汉化方法
- Python3爬取西刺代理前2页国内高匿代理IP并验证有效性,若获取失败,使用快代理获取IP存入表格中
- 蓝牙、红外线与wifi 区别以及不同频段无线电磁波的穿墙和绕过障碍物能力