Scrapy爬取拉勾网职位信息
来源:互联网 发布:保险从业网络继续教育 编辑:程序博客网 时间:2024/05/22 04:31
很多网站都用了一种叫做Ajax(异步加载)的技术,通常我们会发现这种网页,打开了,先给你看上面一部分东西,然后剩下的东西再慢慢加载,也就是局部加载。所以你可以看到很多网页,浏览器中的网址没变,但是数据照样是可以更新的。这对我们正确爬取数据造成了一定影响,我们必须要分析出正确的目标地址才能成功爬取信息。
今天要爬取就的就是这种网站,目标网址是:https://www.lagou.com/zhaopin/
一、目标地址
通过上篇文件的介绍,以上面的目标地址,我们可以很轻松搭建一个爬虫框架。
我的蜘蛛文件代码:
# -*- coding: utf-8 -*-import scrapyclass PositionSpider(scrapy.Spider): name = "position" # allowed_domains = ["lagou.com/zhaopin/"] start_urls = ['http://lagou.com/zhaopin//'] def parse(self, response): file = open("lagou.html", 'w') file.write(response.body) file.close() print response.body
然后打开lagou.html文件,发现页面有点low啊,没关系,能看出一些信息就好。
这里的职位信息和上面图片中显示的职位是一致的,我们就这样简单抓取了吗?是的,其实首页是可以按照前面的方式抓取,但是这里不是我们要抓取的数据。我们要抓取特定条件下的职位信息。
这里我们首先打开开发者工具。
当我们选择条件时,再用上面的地址就抓不到信息了,并且地址栏的地址也发生了变化:https://www.lagou.com/jobs/list_?px=new&city=%E6%9D%AD%E5%B7%9E&district=%E8%A5%BF%E6%B9%96%E5%8C%BA#filterBox,然而再去选择其他条件时就不会发生变化了。
所以很容易想到这里是通过javascript的ajax技术发送的网络请求事件。
在网络面板下我们尝试在过滤器中输入json,对请求进行过滤下。
我们发现了2个资源感觉特别像,其中有个名字直接有position,我们点击右键,在新标签页打开看看。
我们点击open link in new tab。
我们对下这里的内容和网页上的内容是一致的。现在我们可以下结论,我们需要的就是这个网址:
http://www.lagou.com/jobs/positionAjax.json。然后后面可以加这些参数:
gj=应届毕业生&xl=大专&jd=成长型&hy=移动互联网&px=new&city=上海
通过修改这些参数,我们就可以获取不同的职位信息。
注意:这里的构造还比较简单,有时候,有些网址的构造远比这个复杂,经常会出现一些你不知道什么意思的id=什么的,这个时候,可能这个id的可能值可能就在别的文件中,你可能还得找一遍,也可能就在网页源代码中的某个地方。
还有一种情况,可能会出现time=什么的,这就是时间戳,这时候,需要用time函数构造。总之,要具体情况具体分析。
import timetime.time()
二、编写爬虫
1、爬第一页
我们来看下返回的json数据结构:
我们对照这里的层级关系,编写解析json数据的代码。
首先引入json模块:
import json
蜘蛛文件代码:
# -*- coding: utf-8 -*-# coding=utf-8import jsonimport scrapyclass PositionSpider(scrapy.Spider): name = "position" # allowed_domains = ["lagou.com/zhaopin/"] start_urls = ['https://www.lagou.com/jobs/positionAjax.json?px=new&city=%E6%9D%AD%E5%B7%9E&district=%E8%A5%BF%E6%B9%96%E5%8C%BA&needAddtionalResult=false'] def parse(self, response): # print response.body jdict = json.loads(response.body) jcontent = jdict["content"] jposresult = jcontent["positionResult"] jresult = jposresult["result"] for each in jresult: print each['city'] print each['companyFullName'] print each['companySize'] print each['positionName'] print each['secondType'] print each['salary'] print ''
运行下看看效果:
2、爬取更多页
我们可以爬取第一页的数据了,接下来再来看这个请求的具体情况:
通过浏览器的工具提供的信息可以看出,这是一个表单方式提交参数的post请求。下面我们就要模拟这种请求方式。
重写Spider的start_requests方法,并使用FormRequest设置post请求,并且我们可以修改xrang的范围,下载指定范围内页面的数据。代码如下:
# -*- coding: utf-8 -*-import jsonimport scrapyclass PositionSpider(scrapy.Spider): name = "position" # allowed_domains = ["lagou.com/zhaopin/"] start_urls = [ 'https://www.lagou.com/jobs/positionAjax.json?px=new&city=%E6%9D%AD%E5%B7%9E&district=%E8%A5%BF%E6%B9%96%E5%8C%BA&needAddtionalResult=false'] city = u'杭州' district = u'西湖区' url = 'https://www.lagou.com/jobs/positionAjax.json' def start_requests(self): for num in xrange(1, 5): form_data = {'pn': str(num), 'city': self.city, 'district': self.district} headers = { 'Host': 'www.jycinema.com', 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36' } yield scrapy.FormRequest(self.url, formdata=form_data, callback=self.parse) # requests = [] # for num in xrange(1, 5): # requests.append(scrapy.FormRequest(self.url, method='post', formdata={'pn': str(num), 'city': self.city,'district':self.district}, callback=self.parse)) # return requests def parse(self, response): # print response.body jdict = json.loads(response.body) jcontent = jdict["content"] jposresult = jcontent["positionResult"] jresult = jposresult["result"] for each in jresult: print each['city'] print each['companyFullName'] print each['companySize'] print each['positionName'] print each['secondType'] print each['salary'] print ''
运行程序我们可以成功的抓取1-4页的所有职位信息。
这里不提供数据的截图了,因为这里数据是经常变化的。如果你自己去测试一下,肯定和我的数据是不一样的。
3、自动翻页
# -*- coding: utf-8 -*-# coding=utf-8import jsonimport scrapyclass PositionSpider(scrapy.Spider): name = "position" # allowed_domains = ["lagou.com/zhaopin/"] start_urls = [ 'https://www.lagou.com/jobs/positionAjax.json'] totalPageCount = 0 curpage = 1 city = u'杭州' district = u'西湖区' url = 'https://www.lagou.com/jobs/positionAjax.json' # 设置下载延时 # download_delay = 10 def start_requests(self): # for num in xrange(1, 3): # form_data = {'pn': str(num), 'city': self.city, 'district': self.district} # headers = { # 'Host': 'www.jycinema.com', # 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', # 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36' # } # yield scrapy.FormRequest(self.url, formdata=form_data, callback=self.parse) # requests = [] # for num in xrange(1, 5): # requests.append(scrapy.FormRequest(self.url, method='post', formdata={'pn': str(num), 'city': self.city,'district':self.district}, callback=self.parse)) # return requests return [scrapy.FormRequest(self.url,formdata={'pn': str(self.curpage), 'city': self.city,'district':self.district}, callback=self.parse)] def parse(self, response): # print response.body # print response.body.decode('utf-8') print str(self.curpage) + "page" jdict = json.loads(response.body) jcontent = jdict['content'] jposresult = jcontent["positionResult"] pageSize = jcontent["pageSize"] jresult = jposresult["result"] self.totalPageCount = jposresult['totalCount'] / pageSize + 1; for each in jresult: print each['city'] print each['companyFullName'] print each['companySize'] print each['positionName'] print each['secondType'] print each['salary'] print '' if self.curpage <= self.totalPageCount: self.curpage += 1 yield scrapy.http.FormRequest(self.url, formdata={'pn': str(self.curpage), 'city': self.city,'district': self.district}, callback=self.parse)
最后如果要保存数据,请参考上篇文章。
这里针对反爬虫也做了一点策略,例如使用USER AGENT池,通过下面方式可以查看请求所使用的user agent。
当shell载入后,您将得到一个包含response数据的本地 response 变量以及request变量。输入 response.body 将输出response的包体, 输出 request.headers 可以看到request的包头。
应对反爬虫策略:
- 设置download_delay
- 禁止cookies
- 使用user agent池
- 使用IP池
- 分布式爬取
此工程源码已上传github, 点此查看。
- Scrapy爬取拉勾网职位信息
- 使用scrapy爬取拉勾网职位信息
- 利用Scrapy爬取拉勾网某职位信息
- 【图文详解】scrapy爬虫与动态页面——爬取拉勾网职位信息(1)
- 【图文详解】scrapy爬虫与动态页面——爬取拉勾网职位信息(2)
- python3 scrapy 入门级爬虫 爬取数万条拉勾网职位信息
- Python爬虫框架Scrapy实战之定向批量获取职位招聘信息
- Python爬虫框架Scrapy实战教程---定向批量获取职位招聘信息
- Python爬虫框架Scrapy实战之定向批量获取职位招聘信息
- Python爬虫框架Scrapy实战之定向批量获取职位招聘信息
- Python爬虫框架Scrapy实战之定向批量获取职位招聘信息
- Python爬虫框架Scrapy实战之定向批量获取职位招聘信息
- Scrapy爬虫实践之搜索并获取前程无忧职位信息(基础篇)
- scrapy框架下的两个爬虫分工合作爬取智联招聘所有职位信息。
- 使用scrapy+IP代理+多线程爬虫对拉钩网在杭州互联网职位信息的抓取
- Python scrapy 爬取拉勾网招聘信息
- 博士职位信息网站
- JAVA工程师职位信息汇总
- Python笔记004——pycharm下配置pyuic和使用pyuic将.ui转成.py
- 深度分析mysql GROUP BY 与 ORDER BY
- iOS逆向工程工具之Theos
- MySql(单实例-非编译)安装及使用说明
- JAVA数据结构:双端链表
- Scrapy爬取拉勾网职位信息
- 075-C++
- php 数组元素快速去重
- android ble OTA升级(Ti OAD 方案)
- 076-C++
- C语言getchar()、getch()、scanf()对比(一)
- MySQL中MAX函数与Group By一起使用的注意事项
- 字符编码笔记:ASCII,Unicode和UTF-8
- mysql语句汇总