本笔记写于2020年2月4日。Python版本为3.7.4,编辑器是VS codepython
主要参考资料有:json
B站视频av44518113浏览器
Python官方文档安全
PS:若是笔记中有任何错误,欢迎在评论中指出,我会及时回复并修改,谢谢服务器
看B站学习视频的时候,老师讲得第一个实战也就是爬取拉勾网数据是怎么也爬取不下来,弹幕里的方法也都无论用。因此开始求助伟大的度娘,度娘中大部分的解决方法都是使用requests
库来爬取的,但目前只学习的urllib
库,因此没办法采用。cookie
可是,我注意到了一个很是重要的细节,就是爬取不下来数据的缘由。拉勾网的Cookie中使用了时间戳,简单的说,就是拉钩网的cookie中有一个cookie是专门设置时间值的。编辑器
正常浏览器访问页面的时候,浏览器首先获取到了python职位页面对应的HTML文本,再根据HTML文本中的连接请求相应的各类其余数据,而后经过JS代码将其复原为完整页面。正常请求过程当中,这个速度是很是快速的,时间值并不会过时。也就是说,时间值的设置对于拉勾网的正常访问不会有任何影响。ide
但若是按照老师的视频中所说的,咱们直接去爬取保存着职位信息的json
数据,就算是复制了全部的响应头也没有用,由于cookie中的时间值已通过期了。服务器接受到这种爬虫请求后,就会返回您操做太频繁,请稍后再访问这句话了。学习
爬取拉勾网数据的关键就是快,只要时间戳没有超期就能够爬取成功。网站
咱们这里分三个步骤:
json
数据这一步的目的只有一个,就是找到表明时间值的cookie。
首先经过程序,咱们来看一下返回回来的响应头都有什么?
from urllib import request import ssl # 去掉全局安全校验 ssl._create_default_https_context = ssl._create_unverified_context url = 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=' req = request.Request(url, headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36' }) # 开始请求 response = request.urlopen(req) for header in response.getheaders(): print(header)
结果以下:
能够看到共有4个Set-Cookie
的响应头,其中我以为可能表示时间值的响应头是user_trace_token
,由于我从里面看到了时间信息20200204184124
这个时间戳(但我也不肯定)。
既然找到了响应头,咱们接下来就要提取cookie,并构造接下来请求头的cookie。
cookie = '' for header in response.getheaders(): if header[0] == 'Set-Cookie': print(header[1].split(';')[0]) cookie = cookie + header[1].split(';')[0] + '; ' cookie = cookie[:-1] print(cookie)
结果以下:
接下来和老师的代码就没什么区别了,就是要在咱们构造的请求头里加上咱们刚才提取的cookie
# -*- coding: utf-8 -*- from urllib import request from urllib import parse import ssl # 去掉全局安全校验 ssl._create_default_https_context = ssl._create_unverified_context # 先爬取首页python职位的网站以获取Cookie url = 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=' req = request.Request(url, headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36' }) response = request.urlopen(req) # 从响应头中提取Cookie cookie = '' for header in response.getheaders(): if header[0] == 'Set-Cookie': cookie = cookie + header[1].split(';')[0] + '; ' # 去掉最后的空格 cookie = cookie[:-1] # 爬取职位数据 url = 'https://www.lagou.com/jobs/positionAjax.json?city=%E5%8C%97%E4%BA%AC&needAddtionalResult=false' # 构造请求头,将上面提取到的Cookie添加进去 headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36', 'Cookie': cookie, 'Referer': 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=' } data = { 'first': 'true', 'pn': 1, 'kd': 'python' } req = request.Request(url, data=parse.urlencode(data).encode('utf-8'), headers=headers) response = request.urlopen(req) print(response.read().decode('utf-8'))
爬取成功后的结果: