通俗易懂的分析如何用Python实现一只小爬虫,爬取拉勾网的职位信息
时间:2022-04-26
本文章向大家介绍通俗易懂的分析如何用Python实现一只小爬虫,爬取拉勾网的职位信息,主要内容包括效果预览、思路、代码、测试、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
源代码:https://github.com/nnngu/LagouSpider
效果预览
思路
1、首先我们打开拉勾网,并搜索“java”,显示出来的职位信息就是我们的目标。
2、接下来我们需要确定,怎样将信息提取出来。
- 查看网页源代码,这时候发现,网页源代码里面找不到职位相关信息,这证明拉勾网关于职位的信息是异步加载的,这也是一种很常用的技术。
- 异步加载的信息,我们需要借助 chrome 浏览器的开发者工具进行分析,打开开发者工具的方法如下:
- 点击Nerwork进入网络分析界面,这时候是一片空白,刷新一下界面就可以看到一系列的网络请求了。
- 前面我们说到,拉勾网关于职位的信息是异步加载的,那么在这一系列的网络请求中,必定有某个请求发送给服务器,响应回来的是职位信息。
- 正常情况下,我们可以忽略css,图片等类型的请求,关注点放在XHR这种类型请求上,如图:
一共4个XHR类型的请求,我们逐个打开对比,分别点击Preview就能看到它们响应的内容。
发现第一个请求就是我们要找的。如图:
点击Headers,查看一下请求参数。如下图:
到此,我们可以确定city参数就是城市,pn参数就是页数,kd参数就是搜索关键字。
接下来开始写代码了。
代码
代码分成四个部分,便于后期维护。
1、基本 https 请求https.py
这部分对 requests 包进行了一些封装,部分代码如下:
# -*- coding: utf-8 -*-
from src.setting import IP, UA
import requests, random
import logging
class Http:
'''
http请求相关的操作
'''
def __init__(self):
pass
def get(self, url, headers=None, cookies=None, proxy=None, timeOut=5, timeOutRetry=5):
'''
获取网页源码
url: 网页链接
headers: headers
cookies: cookies
proxy: 代理
timeOut: 请求超时时间
timeOutRetry: 超时重试次数
return: 源码
'''
if not url:
logging.error('GetError url not exit')
return 'None'
# 这里只展示了一部分代码
# 完整代码已上传到Github
这里只展示了一部分代码,完整代码已上传到Github
2、代码主逻辑部分main.py
这部分的程序逻辑,如下:
- 获取职位信息
def getInfo(url, para):
"""
获取信息
"""
generalHttp = Http()
htmlCode = generalHttp.post(url, para=para, headers=headers, cookies=cookies)
generalParse = Parse(htmlCode)
pageCount = generalParse.parsePage()
info = []
for i in range(1, 3):
print('第%s页' % i)
para['pn'] = str(i)
htmlCode = generalHttp.post(url, para=para, headers=headers, cookies=cookies)
generalParse = Parse(htmlCode)
info = info + getInfoDetail(generalParse)
time.sleep(2)
return info
- 对信息进行储存
def processInfo(info, para):
"""
信息存储
"""
logging.error('Process start')
try:
title = '公司名称t公司类型t融资阶段t标签t公司规模t公司所在地t职位类型t学历要求t福利t薪资t工作经验n'
file = codecs.open('%s职位.xls' % para['city'], 'w', 'utf-8')
file.write(title)
for p in info:
line = str(p['companyName']) + 't' + str(p['companyType']) + 't' + str(p['companyStage']) + 't' +
str(p['companyLabel']) + 't' + str(p['companySize']) + 't' + str(p['companyDistrict']) + 't' +
str(p['positionType']) + 't' + str(p['positionEducation']) + 't' + str(
p['positionAdvantage']) + 't' +
str(p['positionSalary']) + 't' + str(p['positionWorkYear']) + 'n'
file.write(line)
file.close()
return True
except Exception as e:
print(e)
return None
3、信息解析部分parse.py
这部分针对服务器返回的职位信息的特点,进行解析,如下:
class Parse:
'''
解析网页信息
'''
def __init__(self, htmlCode):
self.htmlCode = htmlCode
self.json = demjson.decode(htmlCode)
pass
def parseTool(self, content):
'''
清除html标签
'''
if type(content) != str: return content
sublist = ['<p.*?>', '</p.*?>', '<b.*?>', '</b.*?>', '<div.*?>', '</div.*?>',
'</br>', '<br />', '<ul>', '</ul>', '<li>', '</li>', '<strong>',
'</strong>', '<table.*?>', '<tr.*?>', '</tr>', '<td.*?>', '</td>',
'r', 'n', '&.*?;', '&', '#.*?;', '<em>', '</em>']
try:
for substring in [re.compile(string, re.S) for string in sublist]:
content = re.sub(substring, "", content).strip()
except:
raise Exception('Error ' + str(substring.pattern))
return content
# 这里只展示了一部分代码
# 完整代码已上传到Github
这里只展示了一部分代码,完整代码已上传到Github
4、配置部分setting.py
这部分加入 cookies 的原因是为了应对拉勾网的反爬,长期使用需要进行改进,进行动态 cookies 获取
# -*- coding: utf-8 -*-
# headers
headers = {
'Host': 'www.lagou.com',
'Connection': 'keep-alive',
'Content-Length': '23',
'Origin': 'https://www.lagou.com',
'X-Anit-Forge-Code': '0',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'X-Requested-With': 'XMLHttpRequest',
'X-Anit-Forge-Token': 'None',
'Referer': 'https://www.lagou.com/jobs/list_java?city=%E5%B9%BF%E5%B7%9E&cl=false&fromSearch=true&labelWords=&suginput=',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7'
}
测试
运行结果:
爬取结束后,在src目录下就可以看到爬虫爬取到的数据。
到此,拉勾网的职位信息抓取就完成了。完整代码已经上传到我的Github
- 如何使用Python Impyla客户端连接Hive和Impala
- 如何在Windows Server2008搭建DNS服务并配置泛域名解析
- 如何通过CM API优雅的获取元数据库密码
- CM启动报InnoDB engine not found分析
- 如何在Hue中使用Sentry
- 如何在Redhat中配置R环境
- 如何在Redhat中安装R的包及搭建R的私有源
- 什么是sparklyr
- 如何利用Dnsmasq构建小型集群的本地DNS服务器
- Cloudera Labs中的Phoenix
- 如何在CDH中使用Phoenix
- Java 8 时间 API 快速入门
- 如何在CDH中使用HPLSQL实现存储过程
- 如何掌握所有的编程语言
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- jQuery实现点击图片弹出视频并自动播放
- 机器学习之决策树一-ID3原理与代码实现
- jQuery点击返回顶部
- 手把手教你,嘴对嘴传达------Nginx实现动静分离的两种方式
- Vue实现push数组并删除方法
- 机器学习之决策树二-C4.5原理与代码实现
- Vue Router懒加载
- 手把手教你,嘴对嘴传达------Tomcat部署和优化以及虚拟主机配置
- 微信小程序使用scroll-view做导航栏
- java解析XML的方法
- 听说Mysql你很豪横?-------------各种数据库介绍(为什么Mysql数据库能这么火热)
- Vuex的简单入门
- 听说Mysql你很豪横?-------------管理MySQL数据库基本操作命令
- Axios安装封装api接口
- 排障集锦:九九八十一难之第七难!mysql数据库登录密码忘记了