转载自:https://www.cnblogs.com/sui776265233/p/11146969.html
代码写得很好,但是目前只看得懂前一部分
一、爬取和分析相关依赖包
- Python版本: Python3.6
- requests: 下载网页
- math: 向上取整
- time: 暂停进程
- pandas:数据分析并保存为csv文件
二、分析网页结构
在拉勾网搜索'python工程师',然后右键点击检查或者F12,,使用检查功能查看网页源代码,当我们点击下一页观察浏览器的搜索栏的url并没有改变,这是因为拉勾网做了反爬虫机制, 职位信息并不在源代码里,而是保存在JSON的文件里,因此我们直接下载JSON,并使用字典方法直接读取数据.即可拿到我们想要的python职位相关的信息
待爬取的python工程师职位信息如下:
为了能爬到我们想要的数据,我们要用程序来模拟浏览器来查看网页,所以我们在爬取的过程中会加上头信息,头信息也是我们通过分析网页获取到的,通过网页分析我们知道该请求的头信息,以及请求的信息和请求的方式是POST请求,这样我们就可以该url请求拿到我们想的数据做进一步处理
爬取网页信息代码如下:
import requests url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false' def get_json(url, num): """ 从指定的url中通过requests请求携带请求头和请求体获取网页中的信息, :return: """ url1 = 'https://www.lagou.com/jobs/list_python%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88?labelWords=&fromSearch=true&suginput=' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 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?labelWords=&fromSearch=true&suginput=', ', 'X-Anit-Forge-Token': 'None', 'X-Requested-With': 'XMLHttpRequest' } data = { 'first': 'true', 'pn': num, 'kd': 'python工程师'} s = requests.Session() print('建立session:', s, '\n\n') s.get(url=url1, headers=headers, timeout=3) cookie = s.cookies print('获取cookie:', cookie, '\n\n') res = requests.post(url, headers=headers, data=data, cookies=cookie, timeout=3) res.raise_for_status() res.encoding = 'utf-8' page_data = res.json() print('请求响应结果:', page_data, '\n\n') return page_data print(get_json(url, 1))
通过搜索我们知道每页显示15个职位,最多显示30页,通过分析网页源代码知道,可以通过JSON里读取总职位数,通过总的职位数和每页能显示的职位数.我们可以计算出总共有多少页,然后使用循环按页爬取, 最后将职位信息汇总, 写入到CSV格式的文件中.
程序运行结果如图:
完整代码如下:
import requests import math import time import pandas as pd def get_json(url, num): """ 从指定的url中通过requests请求携带请求头和请求体获取网页中的信息, :return: """ url1 = 'https://www.lagou.com/jobs/list_python%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88?labelWords=&fromSearch=true&suginput=' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 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?labelWords=&fromSearch=true&suginput=', ', 'X-Anit-Forge-Token': 'None', 'X-Requested-With': 'XMLHttpRequest' } data = { 'first': 'true', 'pn': num, 'kd': 'python工程师'} s = requests.Session() print('建立session:', s, '\n\n') s.get(url=url1, headers=headers, timeout=3) cookie = s.cookies print('获取cookie:', cookie, '\n\n') res = requests.post(url, headers=headers, data=data, cookies=cookie, timeout=3) res.raise_for_status() res.encoding = 'utf-8' page_data = res.json() print('请求响应结果:', page_data, '\n\n') return page_data def get_page_num(count): """ 计算要抓取的页数,通过在拉勾网输入关键字信息,可以发现最多显示30页信息,每页最多显示15个职位信息 :return: """ page_num = math.ceil(count / 15) if page_num > 30: return 30 else: return page_num def get_page_info(jobs_list): """ 获取职位 :param jobs_list: :return: """ page_info_list = [] for i in jobs_list: # 循环每一页所有职位信息 job_info = [] job_info.append(i['companyFullName']) job_info.append(i['companyShortName']) job_info.append(i['companySize']) job_info.append(i['financeStage']) job_info.append(i['district']) job_info.append(i['positionName']) job_info.append(i['workYear']) job_info.append(i['education']) job_info.append(i['salary']) job_info.append(i['positionAdvantage']) job_info.append(i['industryField']) job_info.append(i['firstType']) job_info.append(i['companyLabelList']) job_info.append(i['secondType']) job_info.append(i['city']) page_info_list.append(job_info) return page_info_list def main(): url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false' first_page = get_json(url, 1) total_page_count = first_page['content']['positionResult']['totalCount'] num = get_page_num(total_page_count) total_info = [] time.sleep(10) print("python开发相关职位总数:{},总页数为:{}".format(total_page_count, num)) for num in range(1, num + 1): # 获取每一页的职位相关的信息 page_data = get_json(url, num) # 获取响应json jobs_list = page_data['content']['positionResult']['result'] # 获取每页的所有python相关的职位信息 page_info = get_page_info(jobs_list) print("每一页python相关的职位信息:%s" % page_info, '\n\n') total_info += page_info print('已经爬取到第{}页,职位总数为{}'.format(num, len(total_info))) time.sleep(20) # 将总数据转化为data frame再输出,然后在写入到csv各式的文件中 df = pd.DataFrame(data=total_info, columns=['公司全名', '公司简称', '公司规模', '融资阶段', '区域', '职位名称', '工作经验', '学历要求', '薪资', '职位福利', '经营范围', '职位类型', '公司福利', '第二职位类型', '城市']) df.to_csv('Python_development_engineer.csv', index=False) print('python相关职位信息已保存') if __name__ == '__main__': main()