文章目录

  • 需求分析
  • 项目简介
    • 职位需求页面分析
    • PositionId 数据采集
      • 真实的URL获取
      • 请求头信息
      • 表单信息
      • 返回的JSON数据
    • PositionId 页面解析
    • 数据分析
      • 可视化中文显示问题解决
  • 常见错误及解决方式
    • 在使用 fake_useragen 的时候出现如下错误:
    • 获取页面信息时出现请求频繁问题
  • 项目代码
    • 配置文件(config.py)
    • 数据分析模块(lagou.py)
    • 核心代码(run.py)

需求分析

知己知彼,方可百战不殆。在学习技术的时候我们往往面临太多选择而不知所措,可能是各个方面都有涉猎,对某个领域没有深入研究,看似什么都会,真要让你做个什么东西的时候就显得捉肘见襟。如果我们能从招聘职位所需的技能开始学习,便可练就一身硬功夫,为实战应用中打下良好的基础。通过python抓取拉钩网的招聘详情,并筛选其中的技能关键词,存储到 excel 中。

项目简介

职位需求页面分析

通过观察可以发现,拉勾网的职位页面详情是由 http://www.lagou.com/jobs/PositionId.html 组成。

而 PositionId 可以通过分析 Json 的 XHR 获得。而红框里的职位描述内容是我们要抓取的数据。

知道了数据的源头,接下来就按照常规步骤包装 Headers ,提交 FormData 来获取反馈数据。

PositionId 数据采集

注意:

  • 拉勾网反爬虫做的比较严,请求头多添加几个参数才能不被网站识别.
  • 我们找到真正的请求网址,发现返回的是一个 JSON 串,解析这个 JSON 串即可,而且注意是 POST传值,通过改变 Form Data 中 pn 的值来控制翻页。
  • XHR : XMLHttpRequest 对象用于和服务器交换数据。
    点击页面中的页数,比如第 2 页,我们可以在右边看到一个 POST 请求,这个请求里面包含了真实的URL( 浏览器上的 URL 并没有职位数据,查看源代码就可以发现这一点)、 POST 请求的请求头Headers 、 POST 请求提交的表单 Form Data (这里面包含了页面信息 pn 、搜索的职位信息 kd )

真实的URL获取

请求头信息

我们需要构造的请求头Headers信息,如果这里没有构造好的话,容易被网站识别为爬虫,从而拒绝访问请求。

表单信息

发送POST请求时需要包含的表单信息 Form Data 。

返回的JSON数据

发现需要的职位信息在 content –> positionResult –> result 下,其中包含了工作地点、公司名、职位等信息。 我们只需要保存这个数据就可以了。

至此我们分析完毕网页,下面可以开始爬取过程了。

PositionId 页面解析

获取所需的岗位ID,每一个招聘页面详情都有一个所属的ID索引
核心代码

# 获取所有的职位信息;
position = result['content']['positionResult']['result']
# DataFrame是二维数据格式, 便于后续的分析与处理;
df = pd.DataFrame(position)
修改配置文件 config.py : 添加新的配置信息
# 爬取数据的页数
pages = 100
# 存储信息的csv文件位置
csv_filename = 'lagou.csv'
# 多线程开启的线程数;
ThreadCount = 100修改文件 lagou.py :页面解析
def analyse_PositionID(html):"""根据获取的页面解析每一个招聘页面详情都有一个所属的ID索引:param html::return:"""tag = 'positionId'positions = html['content']['positionResult']['result']df = pd.DataFrame(positions)return df

数据存储:
csv 格式
开启线程池,批量爬取职位信息,并存储于 csv 文件;
修改文件 lagou.py : 封装页面爬取和页面解析的任务;

def task(page):# 拉勾网页面url_start = 'https://www.lagou.com/jobs/list_python'# 真实的拉勾网url地址url_parse = 'https://www.lagou.com/jobs/positionAjax.json?
needAddtionalResult=false'# 获取指定页拉勾网的职位信息, 返回的是json反序列化的结果html = getPositionIDPage(url_start, url_parse, page=page)# pprint.pprint(content)# 解析页面, 返回DataFrame格式的数据;df = analyse_PositionID(html)return  df

修改文件 lagou.py : 将批量爬取的信息存储到 csv 文件中;

def save_as_csv():"""将获取的页面解析后的信息通过多线程的方式以csv格式存储到文件:return:"""# 开启线程池with ThreadPoolExecutor(ThreadCount) as pool:# map方法中,可迭代对象传入函数是从前到后逐个提取元素, 并将结果依次存储到
results中;results = pool.map(task, range(1, pages + 1))# 拼接获取的所有信息, axis=0代表往跨行(down),而axis=1代表跨列(across)total_df = pd.concat(results, axis=0)"""sep: 输出文件的字段分隔符, 默认为逗号;header: 是否写出列名;index: 是否写入行名称(索引);"""   total_df.to_csv(csv_filename, sep=',', header=True, index=False)logging.info("文件%s存储成功" %(csv_filename))return total_df
if __name__ == '__main__':save_as_csv()

数据分析

可视化中文显示问题解决

常见字体库下载网址
将下载好的字体库文 simhei.ttf 存在本机 ~/anaconda3/lib/python3.7/site-
packages/matplotlib/mpl-data/fonts/ttf/ 目录中;
获取字体的缓存位置;
print(matplotlib.font_manager.get_cachedir())
shell命令清空缓存
rm -fr /home/kiosk/.cache/matplotlib

常见错误及解决方式

在使用 fake_useragen 的时候出现如下错误:

raise FakeUserAgentError ('Maximum amount of retries reached')
fake_useragent.errors.FakeUserAgentError : Maximum amount of retries reached

解决方法:

from fake_useragent import UserAgent
# 加这个参数后就可以用了, 在发送请求时把验SSL证书关掉, 设置verify为False
ua = UserAgent(verify_ssl=False)

获取页面信息时出现请求频繁问题

{ 'success' : False, 'msg' : '您操作太频繁,请稍后再访问', 'clientIp' : '113.14.1.254'}

解决方法: 使用 seesion 获取平时可以看到的页面信息, 在通过这个session对象获取真实的 url ;

# 创建一个session对象
session = requests.Session()
# 用session对象发出get请求,设置cookies
session.get(url_start, headers=headers, timeout=3)  # 请求首页获取cookies
cookie = session.cookies  # 为此次获取的cookies
# 用session对象发出另外一个post请求,获取cookies , 返回响应信息
response = session.post(url=url_parse,headers=headers,data=data)

项目代码

配置文件(config.py)

# encoding=utf-8
"""
Date:2019-08-14 10:52
User:LiYu
Email:liyu_5498@163.com"""
from fake_useragent import UserAgentHost = 'www.lagou.com'
Origin = 'https://www.lagou.com'
Referer = 'https://www.lagou.com/jobs/list_python'
Connection = 'keep-alive'
Accept = 'application/json, text/javascript, */*; q=0.01'
ua = UserAgent(verify_ssl=False)  # 取消ssl证书验证
ThreadCount = 100
Pages = 100
CsvFileName = 'lagou.csv'

数据分析模块(lagou.py)

# encoding=utf-8
"""
Date:2019-08-14 11:46
User:LiYu
Email:liyu_5498@163.com"""
import pandas as pd
from config import *
import matplotlib.pyplot as plt
import matplotlib# 配置中文字体和修改字体大小
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['font.family'] = 'sans-serif'
matplotlib.rcParams['font.size'] = 12
# 用来正常显示负号
plt.rcParams['axes.unicode_minus'] = Falsedf = pd.read_csv(CsvFileName)
# print(df.head(5))def showSecondType():# 对某一列数据分组统计secongTypeSeries = df['secondType'].value_counts()# print(secongTypeSeries)plt.figure(figsize=(10, 5))secongTypeSeries.plot.bar()plt.show()def showJobNature():jobNature_Series = df['jobNature'].value_counts()# print(jobNature_Series)plt.figure(figsize=(10, 5))# 饼状图jobNature_Series.plot.pie()plt.show()def showCompany():companyShortNameSeries = df['companyShortName'].value_counts()# print(companyShortNameSeries)# 选取招聘Python相关职位个数大于等于5的公司companyShortNameSeriesGt5 = companyShortNameSeries[companyShortNameSeries > 5]# companyShortNameSeriesGt5 = companyShortNameSeriesplt.figure(figsize=(10, 5))companyShortNameSeriesGt5.plot.bar()plt.show()# 具体看下“数据开发”对应的职位
def showDba():dba = df.loc[df['secondType'] == '数据开发']print('数据开发:', dba)# 看下“数据开发”对应的职位。
def showAi():ai = df.loc[df['secondType'] == '人工智能']print('数据开发', ai)# 看下“后端开发”对应的职位。
def showRd():rd = df.loc[df['secondType'] == '后端开发']print('后端开发', rd)# 看下“测试”对应的职位。
def showQa():qa = df.loc[df['secondType'] == '测试']print('测试', qa)if __name__ == '__main__':showSecondType()showJobNature()showCompany()showDba()showAi()showRd()showQa()

核心代码(run.py)

# encoding=utf-8
"""
Date:2019-08-14 10:08
User:LiYu
Email:liyu_5498@163.com"""
import pprint
import random
import time
import pandas as pd
import requests
from config import *
import logging
from concurrent.futures import ThreadPoolExecutor# logging配置
logging.basicConfig(level=logging.INFO,# 日志格式format='%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s',datefmt='%a, %d %b %Y %H:%N:%S',  # 日期格式filename='lagou.log',filemode='w'
)def getPositionIDPage(url_start, url_parse, page=1, kd='python'):headers = {'User-Agent': ua.random,'Host': Host,'Origin': Referer,'Connection': Connection,'Accept': Accept,'Referer': Referer}data = {'first': False,'pn': str(page),'kd': kd}# proxies = [#     {#         'https': '123.139.56.238:9999',#         'http': '123.139.56.238:9999'#     },#     # {#     #     'https': '218.241.219.226:9999',#     #     'http': '218.241.219.226:9999'#     # }# ]# proxies = random.choice(proxies)try:session = requests.Session()session.get(url_start, headers=headers, timeout=3)# print(session.cookies)response = session.post(url=url_parse, headers=headers, data=data)time.sleep(1)response.raise_for_status()response.encoding = response.apparent_encodingexcept Exception as e:logging.error('页面' + url_parse + '爬取失败:', e)return ''else:logging.info('页面' + url_parse + '爬取成功:' + str(response.status_code))return response.json()def analysePositionID(html):if html:positions = html['content']['positionResult']['result']df = pd.DataFrame(positions)return dfelse:return pd.DataFrame({})def task(page):url_start = 'https://www.lagou.com/jobs/list_python'url_parse = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'html = getPositionIDPage(url_start, url_parse, page=page)# pprint.pprint(content)df = analysePositionID(html)return dfdef saveCsv(pages):with ThreadPoolExecutor(ThreadCount) as pool:results = pool.map(task, range(1, pages + 1))totalDf = pd.concat(results, axis=0)# print(totalDf)totalDf.to_csv(CsvFileName, sep=',', header=True, index=False)logging.info('文件%s存储成功' % CsvFileName)if __name__ == '__main__':saveCsv(PAGES)

爬虫项目实战:拉钩网职位需求采集相关推荐

  1. ruby 爬虫爬取拉钩网职位信息,产生词云报告

    思路:1.获取拉勾网搜索到职位的页数 2.调用接口获取职位id 3.根据职位id访问页面,匹配出关键字 url访问采用unirest,由于拉钩反爬虫,短时间内频繁访问会被限制访问,所以没有采用多线程, ...

  2. python爬虫项目-33个Python爬虫项目实战(推荐)

    今天为大家整理了32个Python爬虫项目. 整理的原因是,爬虫入门简单快速,也非常适合新入门的小伙伴培养信心.所有链接指向GitHub,祝大家玩的愉快~O(∩_∩)O WechatSogou [1] ...

  3. python爬虫知网实例-33个Python爬虫项目实战(推荐)

    今天为大家整理了32个Python爬虫项目. 整理的原因是,爬虫入门简单快速,也非常适合新入门的小伙伴培养信心.所有链接指向GitHub,祝大家玩的愉快~O(∩_∩)O WechatSogou [1] ...

  4. post获取重定向的链接 python_欧美音乐网站Python爬虫项目实战

    爬虫项目实战 0x01 目标分析 最近发现一个比较好的欧美音乐下载网站,可以下载大部分高质量欧美音乐.该爬虫项目要实现自动化批量获取用户想要下载的音乐.本文从网站分析.爬虫设计.代码实现三个方面出发, ...

  5. c++builder 运行网站的api_欧美音乐网站Python爬虫项目实战

    爬虫项目实战 0x01 目标分析 最近发现一个比较好的欧美音乐下载网站,可以下载大部分高质量欧美音乐.该爬虫项目要实现自动化批量获取用户想要下载的音乐.本文从网站分析.爬虫设计.代码实现三个方面出发, ...

  6. python爬虫项目实战教学视频_('[Python爬虫]---Python爬虫进阶项目实战视频',)

    爬虫]---Python 爬虫进阶项目实战 1- Python3+Pip环境配置 2- MongoDB环境配置 3- Redis环境配置 4- 4-MySQL的安装 5- 5-Python多版本共存配 ...

  7. python爬取拉勾网_python爬虫—爬取拉钩网

    本人自学python,小试牛刀,爬取广州片区拉钩网招聘信息.仅用于学习 参考文章:https://blog.csdn.net/SvJr6gGCzUJ96OyUo/article/details/805 ...

  8. python爬虫—爬取拉钩网

    本人自学python,小试牛刀,爬取广州片区拉钩网招聘信息.仅用于学习 参考文章:https://blog.csdn.net/SvJr6gGCzUJ96OyUo/article/details/805 ...

  9. python爬虫新手项目-33个Python爬虫项目实战(推荐)

    今天为大家整理了32个Python爬虫项目. 整理的原因是,爬虫入门简单快速,也非常适合新入门的小伙伴培养信心.所有链接指向GitHub,祝大家玩的愉快~O(∩_∩)O WechatSogou [1] ...

最新文章

  1. 《AI技术人才成长路线图》:完整版PPT及要点解读
  2. 【初体验】valgrind分析程序性能
  3. 手机APP移动应用开发
  4. cassandra 3.x官方文档(5)---探测器
  5. redis的发布和订阅
  6. scala中map与flatMap浅析
  7. 数据通信原理_卫星通信系统原理什么 卫星通信系统原理介绍【图文】
  8. SSM+汽车销售平台 毕业设计-附源码171619
  9. delphi CnPack
  10. SPLUS数据库导入导出操作
  11. 屏幕取色器(Qt实现)(放大镜,RGB显示,智能调节)
  12. 观海智能观海舆情大数据SaaS云平台
  13. 转:怎么判断自己在不在一家好公司?
  14. Office2016 Visio2016 Project2016零售版转换VL版
  15. Android 如何加载网页、图片以及PDF文件之项目实战
  16. 我的学习笔记002--asp.net中的路径mxx
  17. GANs:生成对抗网络系列及应用
  18. springboot feign too many bytes written executing
  19. SAP最佳业务实践:FI-导言
  20. Exchange 2010 SP1个人邮件归档配置

热门文章

  1. 必须掌握的几种最优化方法极其区别
  2. UFT:EXCEL数据驱动——EOM
  3. 【甘道夫】Pandas 基础知识总结
  4. 德鼎创新基金合伙人王岳华加盟SmartMesh生态
  5. nodejs使用forever执行
  6. 设置MaskedTextBox控件的格式,掩码方式检验输入方式
  7. 内网穿透,使用 IPv6 公网访问内网设备踩坑指南
  8. Gyp语法规则参考 工具的使用
  9. jzoj1481. 偷懒的西西
  10. c语言mac小游戏,烧脑又有趣!苹果官方的「编程游戏」登陆Mac